Reputation: 805
Stumped on how to mock a class and be able to assert that its' methods are called with some arguments. When I assert the call i get a "Not called" assertion but, I can see the method call in the mock_calls
attribute.
sandbox/module.py
class Subject(object):
def __init__(self):
pass
def run(self, *args, **kwargs):
reference = Reference(*args, **kwargs)
reference.method_a(*args)
class Reference(object):
def __init__(self, *args, **kwargs):
pass
def method_a(self, *args):
pass
test.py
import unittest
from unittest import mock
from sandbox.module import Subject
class TestSandbox(unittest.TestCase):
@mock.patch('sandbox.module.Reference')
def test_method_calls(self, mock_reference):
subject = Subject()
subject.run(1, 2, 3, x=44, y=55, z=66)
mock_reference.assert_called_with(1, 2, 3, x=44, y=55, z=66)
mock_reference.method_a.assert_called_with(1, 2, 3)
The result is
AssertionError: Expected call: method_a(1, 2, 3)
Not called
The value of mock_reference.mock_calls
is
[
call(1, 2, 3, x=44, y=55, z=66),
call().method_a(1, 2, 3)
]
If I access call as call().method_a
I can access the method details but, the mock_calls
gets a item call()
added to it. Which could change assert_called_once_with
in a way i wouldn't expect and, doesn't feel quite right. Furthermore, if autospec=True
is used I need to pass the params again. Using just call
as in mock_reference.call.method_a
does not work either.
Output of mock_calls
when accessing call().method_a.mock_calls
mock_reference().method_a.mock_calls
[
call(1, 2, 3, x=44, y=55, z=66),
call().method_a(1, 2, 3),
call()
]
mock_reference.assert_called_once_with(1, 2, 3)
AssertionError: Expected 'Reference' to be called once. Called 2 times.
Upvotes: 8
Views: 5996
Reputation: 133929
You mocked a class, yet the second method is called on instance. Change
mock_reference.method_a.assert_called_with(1, 2, 3)
to
mock_reference.return_value.method_a.assert_called_with(1, 2, 3)
Upvotes: 25