Reputation: 1228
I am having a lot of difficulty setting my unit test. I have been using patch but it is not behaving entirely as expected.
I have a decorator at the top of my test function:
@mock.patch('WarningFactory.WarningAPIUpdate')
@mock.patch('WarningFactory.SomethingElse')
def test_send_tc_update(self, other_mock, api_mock):
However when at the end of my function when I try to make the following assertion:
api_mock.send_warning.assert_called_with('IDQ20026', 'IDQ20026')
It fails
I know that is should pass because I run
print api_mock.mock_calls
giving
[call(u'test_api'),
call().send_warning('IDQ20026', 'IDQ20026'),
call().send_warning('IDQ24500', 'IDQ24500')]
I can clearly see the send_warning method being called with the correct values, so why is my assertion failing?
Upvotes: 9
Views: 11157
Reputation: 2484
Based on the print output you mentioned the syntax should probably be:
api_mock.return_value.send_warning.assert_called_with('IDQ20026', 'IDQ20026')
Notice the call().send_warning('IDQ20026', 'IDQ20026')
prefix, which correlates to .return_value
.
But why work so hard? I wrote a helper library to automatically generate the asserts for me.
Just add those lines to print the correct asserts for your case:
import mock_autogen.generator
print(mock_autogen.generator.generate_asserts(api_mock))
Upvotes: 0
Reputation: 343
If user3559247's answer does not work, it may be that you're trying to mock nested objects and you will need to read about chaining mock calls. In my case, I wanted to test this code in a hypothetical class MyAzureBatchClient
that leverages the Azure Python SDK:
def node_counts():
self.batch_client = azure.batch.batch_service_client.BatchServiceClient(...)
self.batch_client.account.list_pool_node_counts()
...
Calling mocked_batch_client.account.list_pool_node_counts.assert_called_with()
failed, although checking the mock_calls
property would showed something similar to you:
[call().list_pool_node_counts()]
However when properly chaining with mocked_batch_client.return_value.account.list_pool_node_counts.assert_called_with()
it works as expected. When checking mocked_batch_client.return_value.account.mock_calls
, note how call.method
is present instead of call().method
:
[call.list_pool_node_counts()]
Upvotes: 0
Reputation: 1228
Looking back now the problem was that assert_called_with only checks the most recent call.
assert_any_call(*args, **kwargs)¶ assert the mock has been called with the specified arguments.
The assert passes if the mock has ever been called, unlike assert_called_with() and assert_called_once_with() that only pass if the call is the most recent one, and in the case of assert_called_once_with() it must also be the only call.
The docs are a little dodgy as they don't mention this under the assert_called_with method.
I ended up using the assert_any_call method for my tests.
Upvotes: 11