Python: Assert that Mock was called with specific Arguments

avatar
Borislav Hadzhiev

Last updated: Apr 11, 2024
4 min

banner

# Table of Contents

  1. Python: Assert that Mock was called with specific Arguments
  2. Using the assert_called_once_with() method instead
  3. Assert that Mock was called with specific Arguments using assert_any_call
  4. Asserting successive calls to a mock method in Python

# Python: Assert that Mock was called with specific Arguments

Use the mock.assert_called_with() method if you need to assert that a Mock was called with specific arguments.

The method asserts that the last call has been made with the supplied arguments.

main.py
from unittest.mock import Mock m = Mock(return_value=None) m('bobby') m.assert_called_with('bobby') m('hadz') m.assert_called_with('hadz') m('com') m.assert_called_with('com')

assert mock called with specific arguments

The assert_called_with method asserts that the last call to the mock was made with the specified arguments.

main.py
from unittest.mock import Mock m = Mock(return_value=None) m('bobby', 'hadz', 'com') m.assert_called_with('bobby', 'hadz', 'com')

using assert called with method

You should also specify the supplied keyword arguments when testing.

main.py
from unittest.mock import Mock m = Mock(return_value=None) m('bobby', 'hadz', 'com', foo='bar') m.assert_called_with('bobby', 'hadz', 'com', foo='bar')

The first 3 arguments in the call to the mock function are positional and the foo argument is a keyword argument.

We passed the arguments to the assert_called_with() method in the exact same way as we passed them when calling the mock.

Note that the assert_called_with method only passes the test if the most recent call to the mock was made with the specified arguments.

# Using the assert_called_once_with() method instead

There is also an assert_called_once_with method that enables you to assert that the mock was called exactly once and the call was made with the specified arguments.

main.py
from unittest.mock import Mock m = Mock(return_value=None) m('bobby', 'hadz', 'com', foo='bar') m.assert_called_once_with('bobby', 'hadz', 'com', foo='bar') m('bobby', 'hadz', 'com', foo='bar') # โ›”๏ธ AssertionError: Expected 'mock' to be called once. Called 2 times. m.assert_called_once_with('bobby', 'hadz', 'com', foo='bar')

The first call to the assert_called_once_with() method succeeds because the mock was called once and was made with the given arguments.

The second call to the method, however, fails because the mock has been called 2 times.

# Assert that Mock was called with specific Arguments using assert_any_call

You can also use the assert_any_call method to assert that a mock has been called with specific arguments.

main.py
from unittest.mock import Mock m = Mock(return_value=None) m('bobby', 'hadz', 'com', foo='bar') m('a', 'b', 'c') m.assert_any_call('bobby', 'hadz', 'com', foo='bar')

The assert_any_call method passes if the mock has ever been called with the supplied arguments.

This is not the behavior when using assert_called_with and assert_called_once_with because they only pass if the most recent call was made with the specified arguments.

The assert_any_call method can also be used if you need to check if the mock was called multiple times, with specific arguments in no particular order.

main.py
from unittest.mock import Mock m = Mock(return_value=None) m('bobby') m('hadz') m('com') m.assert_any_call('hadz') m.assert_any_call('bobby') m.assert_any_call('com') assert m.call_count == 3
  1. The calls to assert_any_call() test that the mock was called with specific arguments in no particular order.
  2. The assert statement at the end tests that the mock was called exactly 3 times.

# Asserting successive calls to a mock method in Python

If you need to assert successive calls to a mock method, use the assert_has_calls() method.

main.py
from unittest.mock import call, Mock m = Mock(return_value=None) m('bobby') m('hadz') m('com') calls = [call('bobby'), call('hadz'), call('com')] m.assert_has_calls(calls)

The assert_has_calls method asserts that the mock has been called with the specified calls.

We called the mock 3 times and asserted that it has been called 3 times with the exact same arguments.

If you reorder the calls, you'll get an error.

main.py
from unittest.mock import call, Mock m = Mock(return_value=None) m('bobby') m('hadz') m('com') # ๐Ÿ‘‡๏ธ Reordered calls calls = [call('hadz'), call('bobby'), call('com')] # โ›”๏ธ AssertionError: Calls not found. # Expected: [call('hadz'), call('bobby'), call('com')] # Actual: [call('bobby'), call('hadz'), call('com')] m.assert_has_calls(calls)

If you don't care about the order of the calls and just want to check that the mock has been called with the specified arguments, supply the any_order keyword argument in the call to assert_has_calls().

main.py
from unittest.mock import call, Mock m = Mock(return_value=None) m('bobby') m('hadz') m('com') # ๐Ÿ‘‡๏ธ Reordered calls calls = [call('hadz'), call('bobby'), call('com')] # โœ… Passes m.assert_has_calls(calls, any_order=True)

If the any_order keyword argument is set to True, the calls can be in any order but they all must appear in the mock's calls.

If any_order is set to False, then the calls must be sequential.

You can view the calls of the mock by accessing the mock_calls attribute.

main.py
from unittest.mock import call, Mock m = Mock(return_value=None) m('bobby') m('hadz') m('com') # [call('bobby'), call('hadz'), call('com')] print(m.mock_calls)

The mock_calls attribute records all calls to the mock object, its methods, magic methods and return value mocks.

The items in the list are unittest.mock.call objects.

There is also a call_args_list attribute.

main.py
from unittest.mock import Mock m = Mock(return_value=None) m('bobby') m('hadz') m('com') m.assert_any_call('hadz') m.assert_any_call('bobby') m.assert_any_call('com') # ๐Ÿ‘‡๏ธ [call('bobby'), call('hadz'), call('com')] print(m.call_args_list)

The call_args_list attribute is a list of all of the calls made to the mock object in sequence.

The length of the call_args_list attribute is equal to the number of times the mock has been called.

Just like with mock_calls, items in the call_args_list are call objects.

I've also written a detailed guide on how to Mock multiple return values in a Python unit test.

# Additional Resources

You can learn more about the related topics by checking out the following tutorials:

I wrote a book in which I share everything I know about how to become a better, more efficient programmer.
book cover
You can use the search field on my Home Page to filter through all of my articles.

Copyright ยฉ 2024 Borislav Hadzhiev