Here's a toy example that illustrates my problem.
Code
class Bar:
def do_a_thing(self):
print('doing a thing')
class BarSupplier:
def get_bar(self) -> Bar:
return Bar()
class Foo:
def __init__(self, bar_supplier: BarSupplier):
self.bar_supplier = bar_supplier
def do_foo(self):
self.bar_supplier.get_bar().do_a_thing()
Tests
from unittest import TestCase
from unittest.mock import MagicMock, call
from calls_example import Foo
class TestCallsExample(TestCase):
def test_once(self):
bar_supplier = MagicMock()
bar_supplier.get_bar.return_value = MagicMock()
foo = Foo(bar_supplier)
foo.do_foo()
bar_supplier.get_bar.assert_has_calls([
call(),
])
def test_twice(self):
bar_supplier = MagicMock()
bar_supplier.get_bar.return_value = MagicMock()
foo = Foo(bar_supplier)
foo.do_foo()
foo.do_foo()
bar_supplier.get_bar.assert_has_calls([
call(),
call()
])
Results
The first test passes.
The second test fails, with the following exception:
Failure
Traceback (most recent call last):
...
AssertionError: Calls not found.
Expected: [call(), call()]
Actual: [call(), call().do_a_thing(), call(), call().do_a_thing()]
This feels like really strange behaviour - I'm asserting about calls to the get_bar method on the bar_supplier mock, but then the calls list includes calls to a different mock which is returned by the get_bar method.
I'm sure this is a misunderstanding rather than a bug, but how can I best avoid getting those .do_a_thing() calls in my list of calls?