How to check for mock calls with wildcards?
Question:
I am writing unit tests, and want to check for a call which has a function object, like so:
call(u'mock', u'foobar', <function <lambda> at 0x1ea99b0>, 10)
How do I check that the call() has all the parameters I want, without reproducing the lambda?
Edit: I wanted to clarify that I am using the mock
library from here: http://mock.readthedocs.org/en/latest/. The call
I showed above is a call on a MagicMock
object, which I want to check using assert_has_calls
.
Answers:
not sure how you’re building the call
, but if it’s some sort of args
:
# IN THE CASE WE'RE DOING call(*args)
if all([len(args) == 4,isinstance(args[0],str),
isinstance(args[1],str), hasattr(args[2],'__call__'),
isinstance(args[3],int)]):
# PASS
else:
# FAIL
If you’re overly concerned about getting input that is a callable that ISN’T a function, and feel it will fail the unit test silently:
from types import FunctionType
isinstance(lambda x: x,FunctionType) # True
I finally found out how to do what I want. Basically, when using assert_has_calls
, I wanted one parameter to match regardless of what it was (because I can’t recreate the lambda
every time during test).
The way to do it is to use mock.ANY
.
So, in my example, this could match the call:
mocked_object.assert_has_calls([
call('mock', 'foobar', mock.ANY, 10)
])
If you want more granularity than mock.ANY, you can make your own validator class for use in call comparisons like assert_has_calls, assert_called_once_with, etc.
class MockValidator(object):
def __init__(self, validator):
# validator is a function that takes a single argument and returns a bool.
self.validator = validator
def __eq__(self, other):
return bool(self.validator(other))
Which can be used like:
import mock
my_mock = mock.Mock()
my_mock('foo', 8)
# Raises AssertionError.
my_mock.assert_called_with('foo', MockValidator(lambda x: isinstance(x, str)))
# Does not raise AssertionError.
my_mock.assert_called_with('foo', MockValidator(lambda x: isinstance(x, int)))
I am writing unit tests, and want to check for a call which has a function object, like so:
call(u'mock', u'foobar', <function <lambda> at 0x1ea99b0>, 10)
How do I check that the call() has all the parameters I want, without reproducing the lambda?
Edit: I wanted to clarify that I am using the mock
library from here: http://mock.readthedocs.org/en/latest/. The call
I showed above is a call on a MagicMock
object, which I want to check using assert_has_calls
.
not sure how you’re building the call
, but if it’s some sort of args
:
# IN THE CASE WE'RE DOING call(*args)
if all([len(args) == 4,isinstance(args[0],str),
isinstance(args[1],str), hasattr(args[2],'__call__'),
isinstance(args[3],int)]):
# PASS
else:
# FAIL
If you’re overly concerned about getting input that is a callable that ISN’T a function, and feel it will fail the unit test silently:
from types import FunctionType
isinstance(lambda x: x,FunctionType) # True
I finally found out how to do what I want. Basically, when using assert_has_calls
, I wanted one parameter to match regardless of what it was (because I can’t recreate the lambda
every time during test).
The way to do it is to use mock.ANY
.
So, in my example, this could match the call:
mocked_object.assert_has_calls([
call('mock', 'foobar', mock.ANY, 10)
])
If you want more granularity than mock.ANY, you can make your own validator class for use in call comparisons like assert_has_calls, assert_called_once_with, etc.
class MockValidator(object):
def __init__(self, validator):
# validator is a function that takes a single argument and returns a bool.
self.validator = validator
def __eq__(self, other):
return bool(self.validator(other))
Which can be used like:
import mock
my_mock = mock.Mock()
my_mock('foo', 8)
# Raises AssertionError.
my_mock.assert_called_with('foo', MockValidator(lambda x: isinstance(x, str)))
# Does not raise AssertionError.
my_mock.assert_called_with('foo', MockValidator(lambda x: isinstance(x, int)))