[TIP] mock os.walk

Andrea Crotti andrea.crotti.0 at gmail.com
Thu Mar 22 07:36:25 PDT 2012


On 03/22/2012 02:22 PM, Andrea Crotti wrote:
> I wrote in the other thread but I'd better start a new one.
> I simply want to mock os.walk making it iterates over a list.
>
> So what's wrong with the following I really don't get it?
>
> from mock import MagicMock, patch
> from os import walk
>
> test_dir = [
>     ('root', ['d1, .git'], []),
> ]
>
>
> my_mock = MagicMock()
> my_mock.__iter__ = iter(test_dir)
>
>
> @patch('os.walk', new=my_mock)
> def myfun():
>     for r, ds, df in walk('.'):
>         print(df)
>
>
> I get a
>
> Traceback (most recent call last):
>   File "mock_walk.py", line 10, in <module>
>     my_mock.__iter__ = iter(test_dir)
>   File 
> "/home/andrea/.local/lib/python2.7/site-packages/mock-0.8.0beta4-py2.7.egg/mock.py", 
> line 795, in __setattr__
>     value = mocksignature(value, real, skipfirst=True)
>   File 
> "/home/andrea/.local/lib/python2.7/site-packages/mock-0.8.0beta4-py2.7.egg/mock.py", 
> line 320, in mocksignature
>     signature, func = _getsignature(func, skipfirst)
>   File 
> "/home/andrea/.local/lib/python2.7/site-packages/mock-0.8.0beta4-py2.7.egg/mock.py", 
> line 153, in _getsignature
>     func = func.__call__
> AttributeError: 'listiterator' object has no attribute '__call__'
>
>
> but what I don't understand is why we would need the call method, 
> isn't the for loop triggering the __iter__ only?

Ok I understood that error

from mock import MagicMock, patch
import os

test_dir = [
     ('root', ['d1, .git'], []),
]

my_mock = MagicMock()
my_mock.__iter__ = lambda _: iter(test_dir)


@patch('os.walk', new=my_mock)
def myfun():
     for r, ds, df in os.walk('.'):
         print(r, ds, df)

myfun()


and I have to actually assign __iter__ to a function, not just the 
iterable..
Now everything works but still os.walk('.') doesn't return anything, 
even if I really think it shoud,
anything else missing/ wrong??



More information about the testing-in-python mailing list