stopall does not always stop all patches to single target
http://code.google.com/p/mock/issues/detail?id=226
What steps will reproduce the problem?
python code to reproduce error
import mock
def myfunc():
return 'hello'
m = mock.patch('__main__.myfunc').start()
m.return_value = 'firstmock'
myfunc()
m2 = mock.patch('__main__.myfunc').start()
m2.return_value = 'secondmock'
myfunc()
mock.patch.stopall()
myfunc()
What is the expected output? What do you see instead?
I would expect the output from above to be:
'firstmock'
'secondmock'
'hello'
Instead, sometimes it comes out as:
'firstmock'
'secondmock'
'firstmock'
This result is non-deterministic though so it may also come out as expected. Re-run several times to get the error.
This is a result of using a set to store the active patches. Conversion from a set to a list is non-deterministic because the set has no notion of order.
Please provide any additional information below.
This use case may seem strange, but it shows up in large unit tests where a base class sets up a default patch to catch external calls or something similar and then an individual unit test requiring specific mock behavior patches it differently.
I have a patch here that fixes the problem using a list to store the patches to maintain order and call them in reverse order to stop them in the correct order.
https://code.google.com/r/blak111-mockfix/source/detail?r=3c2f72b0253075d628afb333a79b7cb118132294
|