I've got a bit of code that makes a call to a series of methods on each item in a collection, and each method returns a boolean value indicating success = True/failure = False.
def monkey(some_collection, arg1, arg2):
for item in some_collection:
if not item.foo(arg1, arg2):
continue
if not item.bar(arg1, arg2):
continue
if not item.baz(arg1, arg2):
continue
And, here's my unit test example:
import mock
def TestFoo(unittest.TestCase):
def test_monkey(self):
item = MagicMock()
some_collection = [item]
collection_calls = []
foo_call = mock.call().foo(some_collection, 1, 2)
bar_call = mock.call().bar(some_collection, 1, 2)
baz_call = mock.call().baz(some_collection, 1, 2)
collection_calls = [foo_call, bar_call, baz_call]
my_module.monkey(some_collection, 1, 2)
item.assert_has_calls(collection_calls) # requires the correct call order/sequence
Actual Calls
call().foo(<MagicMock id='12345'>, 1, 2)
call().foo.__nonzero__()
...
NOTE: This unit test fails because its seeing the __nonzero__()
method calls.
Question
Why is it adding the nonzero method calls?
Clarification
I'm using mock, which is included in stdlib as of python 3.3.
If your mocked function does not have an explicit return_value or side_effect that returns, you will see this as Python attempts to evaluate the truthiness of your mock. Ensure your mock has one.
Either initialise it with one:
item = MagicMock(return_value=True)
or add one in:
item.return_value = True
When you do if not x:
, you are probably thinking if x is False
.
Python doesn't actually do this - it does if bool(x) is False
(this is Python's truthiness concept - that values evaluate to True
or False
), and bool(x)
is actually a call to x.__nonzero__()
(or x.__bool__()
in 3.x).
This is to provide Python's nice if
behaviour - when you do if []:
, a lot of languages would treat any object as True
, but Python is designed to make code readable, so it delegates and a list's __nonzero__()
method will return False
if it is empty. This allows for more code that reads more naturally, and explains why you will see these calls.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With