To start, I'm using the pytest-mock and pytest packages to test a software project that I'm working on.
I have a situation where I'm testing a class in a module and trying to mock out a composite object that it instantiates from its __init__ method. When I do this, I am able to assert that the __init__ method is properly called, but when I try to assert that an instance method is called, I get an assertion error.
When I debug pytest by passing the --pdb option to it, I verify by checking the MagicMock() object's .method.called property that it "wasn't" called, but then when I check the MagicMock() object's .method_calls property, I see that it was in fact called.
Here's a simple example to show what I mean:
test.py
import module
def test_Calling(mocker):
mocker.patch('module.Called', autospec=True)
module.Calling('argument')
module.Called.assert_called_once_with('argument')
module.Called.check_me.assert_called_once()
module.py
class Calling(object):
def __init__(self, argument):
called_instance = Called(argument)
called_instance.check_me()
class Called(object):
def __init__(self, argument):
pass
def check_me(self):
pass
And here's the pytest/pdb session:
(venv) C:\pytest-issue>pytest --pdb test.py
============================= test session starts =============================
platform win32 -- Python 2.7.12, pytest-3.0.6, py-1.4.32, pluggy-0.4.0
rootdir: C:\pytest-issue, inifile:
plugins: mock-1.5.0
collected 1 items
test.py F
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> traceback >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
mocker = <pytest_mock.MockFixture object at 0x000000000431B2E8>
def test_Calling(mocker):
mocker.patch('module.Called', autospec=True)
module.Calling('argument')
module.Called.assert_called_once_with('argument')
> module.Called.check_me.assert_called_once()
test.py:9:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_mock_self = <MagicMock name='Called.check_me' spec='instancemethod' id='70367608'>
def assert_called_once(_mock_self):
"""assert that the mock was called only once.
"""
self = _mock_self
if not self.call_count == 1:
msg = ("Expected '%s' to have been called once. Called %s times." %
(self._mock_name or 'mock', self.call_count))
> raise AssertionError(msg)
E AssertionError: Expected 'check_me' to have been called once. Called 0 times.
venv\lib\site-packages\mock\mock.py:915: AssertionError
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> entering PDB >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
> c:\pytest-issue\venv\lib\site-packages\mock\mock.py(915)assert_called_once()
-> raise AssertionError(msg)
(Pdb) up
> c:\pytest-issue\test.py(9)test_Calling()
-> module.Called.check_me.assert_called_once()
(Pdb) module.Called.method_calls
[call().check_me()]
(Pdb) module.Called.check_me.called
False
For the life of me, I'm not sure what I'm doing wrong. In this circumstance, do I need to assert .Called.method_calls? If so, that looks like I would have to put a lot of logic into my tests, which is not desirable.