[TIP] mock os.walk

Michael Foord michael at voidspace.org.uk
Thu Mar 22 08:13:03 PDT 2012


On 22/03/2012 15:04, Andrea Crotti wrote:
> On 03/22/2012 02:47 PM, Andrea Crotti wrote:
>>
>> Looking around I found out that this:
>> my_mock = Mock(return_value=iter(test_dir))
>>
>> actually works perfectly, even if I'm not sure why...
>> I would still like to know why my MagicMock is not returning anything 
>> though..
>
> Puff I finally solved all my problems and all the tests are passing :)
>
> I found another thing which I think is at least counter-intuitive.
>
> This below will not work as expected:
>
> my_mock = Mock(return_value=iter(test_dir))
>
> @patch('os.walk', new=my_mock)
> def myfun2():
>     for r, ds, df in os.walk('.'):
>         print(r, ds, df)
>
>
> @patch('os.walk', new=my_mock)
> def myfun3():
>     for r, ds, df in os.walk('.'):
>         print(r, ds, df)
>
>
> myfun2()
> myfun3()
>
> because the iterator is consumed the first run and in the second run 
> there it will just
> return the empty list.
> Is it the desired behaviour?

Well, it may or may not be desired - but it is what you have told mock 
to do. :-)

If you're using mock 0.8 you can do:

     @patch('os.walk', return_value=iter(test_dir))
     def test(mock_walk):
         ...

This creates a new mock instead of a pre-created one. If you really 
*want* to use a single mock for all your tests then you can use a 
side_effect to create and return a fresh iterator every time:

     my_mock = Mock(side_effect=lambda *a, **kw: iter(test_dir))

HTH,

Michael

>
> _______________________________________________
> testing-in-python mailing list
> testing-in-python at lists.idyll.org
> http://lists.idyll.org/listinfo/testing-in-python
>


-- 
http://www.voidspace.org.uk/

May you do good and not evil
May you find forgiveness for yourself and forgive others
May you share freely, never taking more than you give.
-- the sqlite blessing http://www.sqlite.org/different.html




More information about the testing-in-python mailing list