Rolling backport of unittest.mock for all Pythons
—
The mock library provides several special objects and constants for flexible mock assertions, unique object creation, and advanced testing patterns.
A special object that equals anything, useful in mock assertions when you don't care about specific argument values.
class _ANY:
def __eq__(self, other):
"""Always returns True, equals anything."""
return True
def __repr__(self):
"""String representation."""
return '<ANY>'
ANY: _ANYA factory for creating call objects that represent method calls with arguments, used in mock assertions.
class _Call:
def __init__(self, *args, **kwargs):
"""
Create a call object representing a method call.
Parameters:
- *args: Positional arguments for the call
- **kwargs: Keyword arguments for the call
"""
def __eq__(self, other):
"""Compare with another call object or actual call."""
def __repr__(self):
"""String representation of the call."""
def call_list(self):
"""Return as a list of calls (for method chains)."""
call: _CallA factory for creating unique sentinel objects, useful for creating distinct marker values in tests.
class _Sentinel:
def __getattr__(self, name):
"""
Create a unique sentinel object for the given name.
Parameters:
- name: Name of the sentinel to create
Returns:
Unique sentinel object that only equals itself
"""
sentinel: _SentinelA special sentinel value used to represent default behavior in mock side_effect and return_value.
DEFAULT: object # Special sentinel for default mock behaviorA boolean constant that controls whether dir() filtering is applied to mock objects.
FILTER_DIR: bool # Controls dir() filtering on mocksException raised when an invalid specification is provided to mock objects.
class InvalidSpecError(Exception):
"""
Exception raised when an invalid value is used as a mock spec.
This exception is raised when spec or spec_set parameters
contain invalid specifications for mock objects.
"""from mock import Mock, ANY
mock_func = Mock()
mock_func('arg1', 'arg2', kwarg='value')
# These assertions all pass
mock_func.assert_called_with('arg1', 'arg2', kwarg='value') # Exact match
mock_func.assert_called_with(ANY, 'arg2', kwarg='value') # ANY for first arg
mock_func.assert_called_with('arg1', ANY, kwarg=ANY) # ANY for multiple args
mock_func.assert_called_with(ANY, ANY, kwarg=ANY) # ANY for all argsfrom mock import Mock, ANY
mock_func = Mock()
mock_func([1, 2, 3], {'key': 'value'}, some_object)
# Don't care about specific list contents or dict contents
mock_func.assert_called_with(ANY, ANY, some_object)
# Mix ANY with specific values
mock_func.assert_called_with([1, 2, 3], ANY, ANY)from mock import Mock, call
mock_obj = Mock()
mock_obj.method('arg1')
mock_obj.method('arg2', kwarg='value')
mock_obj.other_method()
# Check specific calls
expected_calls = [
call.method('arg1'),
call.method('arg2', kwarg='value'),
call.other_method()
]
mock_obj.assert_has_calls(expected_calls)
# Check calls in any order
mock_obj.assert_has_calls(expected_calls, any_order=True)from mock import Mock, call
mock_func = Mock()
mock_func('first', 'call')
mock_func('second', kwarg='call')
# Represent direct function calls
expected_calls = [
call('first', 'call'),
call('second', kwarg='call')
]
mock_func.assert_has_calls(expected_calls)from mock import sentinel
# Create unique sentinel values
UNIQUE_VALUE = sentinel.UNIQUE_VALUE
ANOTHER_VALUE = sentinel.ANOTHER_VALUE
MISSING = sentinel.MISSING
# Sentinels are only equal to themselves
assert UNIQUE_VALUE == sentinel.UNIQUE_VALUE
assert UNIQUE_VALUE != ANOTHER_VALUE
assert UNIQUE_VALUE != 'anything else'
# Useful for default parameters and special values
def function_with_default(arg=sentinel.DEFAULT):
if arg is sentinel.DEFAULT:
return 'no argument provided'
return f'argument was: {arg}'
assert function_with_default() == 'no argument provided'
assert function_with_default('value') == 'argument was: value'from mock import Mock, sentinel
# Use sentinels as distinctive return values
mock_obj = Mock()
mock_obj.method1.return_value = sentinel.METHOD1_RESULT
mock_obj.method2.return_value = sentinel.METHOD2_RESULT
result1 = mock_obj.method1()
result2 = mock_obj.method2()
assert result1 is sentinel.METHOD1_RESULT
assert result2 is sentinel.METHOD2_RESULT
assert result1 != result2from mock import Mock, DEFAULT
def side_effect_func(*args, **kwargs):
if args[0] == 'special':
return 'special handling'
return DEFAULT # Use default mock behavior
mock_func = Mock(return_value='default result')
mock_func.side_effect = side_effect_func
# Special case uses side_effect
result1 = mock_func('special')
assert result1 == 'special handling'
# Other cases use default return_value
result2 = mock_func('normal')
assert result2 == 'default result'from mock import Mock, call, ANY
class TestService:
def __init__(self):
self.api = Mock()
def process_items(self, items):
for item in items:
self.api.process(item['id'], item['data'], timestamp=ANY)
if item.get('urgent'):
self.api.notify('urgent', item['id'])
# Test the service
service = TestService()
items = [
{'id': 1, 'data': 'test1'},
{'id': 2, 'data': 'test2', 'urgent': True}
]
service.process_items(items)
# Verify all expected calls were made
expected_calls = [
call.process(1, 'test1', timestamp=ANY),
call.process(2, 'test2', timestamp=ANY),
call.notify('urgent', 2)
]
service.api.assert_has_calls(expected_calls)from mock import Mock, call, ANY, sentinel
mock_service = Mock()
# Use sentinel for unique values and ANY for flexible matching
PROCESSING_STATE = sentinel.PROCESSING
COMPLETED_STATE = sentinel.COMPLETED
mock_service.update_status(item_id=123, status=PROCESSING_STATE, metadata=ANY)
mock_service.update_status(item_id=123, status=COMPLETED_STATE, result='success')
expected_calls = [
call.update_status(item_id=123, status=PROCESSING_STATE, metadata=ANY),
call.update_status(item_id=123, status=COMPLETED_STATE, result='success')
]
mock_service.assert_has_calls(expected_calls)from mock import Mock, FILTER_DIR
# Control dir() behavior on mocks
original_filter = FILTER_DIR
# Disable filtering to see all mock attributes
FILTER_DIR = False
mock_obj = Mock()
all_attrs = dir(mock_obj) # Shows internal mock attributes
# Re-enable filtering for cleaner dir() output
FILTER_DIR = True
clean_attrs = dir(mock_obj) # Shows only user-defined attributes
# Restore original setting
FILTER_DIR = original_filterInstall with Tessl CLI
npx tessl i tessl/pypi-mock