A friend of mine described to me a PITA he had with mock - it doesn't play well with a common Python idiom:
if collection:
for element in collection:
do_something(element)
What he expected as default behaviour was for the mock to be iteratable as an empty collection. Instead, he got:>>> m = mock.Mock()
>>> for x in m:
... print x
...
Traceback (most recent call last):
File "", line 1, in
TypeError: 'Mock' object is not iterable
As it turns out, there is a simple solution to this problem: all you need to do is to implement the magic method yourself.>>> class FalseMock(mock.Mock):
... def __nonzero__(self):
... return False
This behaves as you would expect: It evaluates to False.>>> m = FalseMock()
>>> bool(m)
False
It still works as every other Mock object would:>>> m.a.b.c.d.return_value = "hi"
>>> m.a.b.c.d()
'hi'
It keeps its behaviour in all Mocks generated as a result of getting an attribute>>> m.a.b.c.d