Type stubs for the mock library providing comprehensive type annotations for Mock, MagicMock, patch decorators, and other testing utilities
Helper functions and specialized mock classes for common testing scenarios. These utilities provide enhanced functionality for automatic spec creation, file mocking, property mocking, and mock validation to streamline test development.
Automatically create mocks that match the interface of target objects.
def create_autospec(
spec,
spec_set: bool = False,
instance: bool = False,
_parent=None,
_name=None,
*,
unsafe: bool = False,
**kwargs
):
"""
Create a mock with automatic specification based on another object.
Parameters:
- spec: Object to create specification from
- spec_set: If True, attempting to access non-existent attributes raises AttributeError
- instance: If True, mock represents an instance rather than the class itself
- unsafe: Allow mocking of built-in types and methods
- **kwargs: Additional arguments passed to Mock constructor
Returns:
Mock object that matches the interface of spec
"""Usage examples:
from mock import create_autospec
class Calculator:
def add(self, a: int, b: int) -> int:
return a + b
def multiply(self, a: int, b: int) -> int:
return a * b
# Create mock with automatic spec
calc_mock = create_autospec(Calculator, spec_set=True)
# Mock has same interface as Calculator
calc_mock.add.return_value = 10
result = calc_mock.add(5, 3)
assert result == 10
# Accessing non-existent method raises AttributeError (with spec_set=True)
try:
calc_mock.nonexistent_method()
except AttributeError:
pass # Expected behavior
# Create instance mock
calc_instance_mock = create_autospec(Calculator, instance=True)
calc_instance_mock.add.return_value = 15
assert calc_instance_mock.add(7, 8) == 15
# Function autospec
def original_function(x: int, y: str = "default") -> str:
return f"{y}: {x}"
func_mock = create_autospec(original_function)
func_mock.return_value = "mocked result"
result = func_mock(42, y="test")
assert result == "mocked result"
func_mock.assert_called_once_with(42, y="test")Create mock file-like objects for testing file operations.
def mock_open(mock=None, read_data: str = ""):
"""
Create a mock that simulates file operations.
Parameters:
- mock: Existing mock to configure (creates new MagicMock if None)
- read_data: String data that read() and readline() methods will return
Returns:
Mock object that behaves like a file
"""Usage examples:
from mock import mock_open, patch
# Basic file mocking
def test_file_reading():
with patch('builtins.open', mock_open(read_data="file content")) as mock_file:
with open('test.txt', 'r') as f:
content = f.read()
assert content == "file content"
mock_file.assert_called_once_with('test.txt', 'r')
# Multi-line file content
def test_multiline_file():
file_content = "line 1\nline 2\nline 3"
with patch('builtins.open', mock_open(read_data=file_content)):
with open('test.txt', 'r') as f:
lines = f.readlines()
assert lines == ["line 1\n", "line 2\n", "line 3"]
# Test file writing
def test_file_writing():
with patch('builtins.open', mock_open()) as mock_file:
with open('test.txt', 'w') as f:
f.write("test content")
mock_file.assert_called_once_with('test.txt', 'w')
mock_file().write.assert_called_once_with("test content")
# Complex file operations
def test_file_operations():
mock_file_data = mock_open(read_data="initial content")
with patch('builtins.open', mock_file_data):
# Test reading
with open('file.txt', 'r') as f:
content = f.read()
assert content == "initial content"
# Test writing
with open('file.txt', 'w') as f:
f.write("new content")
# Verify calls
mock_file_data.assert_any_call('file.txt', 'r')
mock_file_data.assert_any_call('file.txt', 'w')Mock property attributes and descriptors.
class PropertyMock(Mock):
def __init__(self, *args, **kwargs) -> None:
"""Create a mock for property objects."""
def __get__(self, obj, obj_type=None):
"""Descriptor get method - called when property is accessed."""
def __set__(self, obj, value) -> None:
"""Descriptor set method - called when property is assigned."""Usage examples:
from mock import PropertyMock, patch
class MyClass:
@property
def value(self):
return self._value
@value.setter
def value(self, val):
self._value = val
# Mock property directly
def test_property_mock():
obj = MyClass()
with patch.object(MyClass, 'value', new_callable=PropertyMock) as mock_prop:
mock_prop.return_value = "mocked_value"
# Test property access
assert obj.value == "mocked_value"
mock_prop.__get__.assert_called_once()
# Test property assignment
obj.value = "new_value"
mock_prop.__set__.assert_called_once_with(obj, "new_value")
# Property with side effects
def test_property_side_effect():
obj = MyClass()
with patch.object(MyClass, 'value', new_callable=PropertyMock) as mock_prop:
# Different behavior on successive calls
mock_prop.side_effect = ["first", "second", "third"]
assert obj.value == "first"
assert obj.value == "second"
assert obj.value == "third"
# Mock computed property
class ComputedClass:
@property
def computed(self):
return len(self.data) * 2
def test_computed_property():
obj = ComputedClass()
with patch.object(ComputedClass, 'computed', new_callable=PropertyMock) as mock_prop:
mock_prop.return_value = 42
assert obj.computed == 42
mock_prop.__get__.assert_called_once()Prevent accidental attribute access on mocks.
def seal(mock) -> None:
"""
Seal a mock to prevent creation of new attributes.
Parameters:
- mock: Mock object to seal
After sealing, accessing non-existent attributes raises AttributeError.
"""Usage examples:
from mock import Mock, seal
# Basic sealing
def test_mock_sealing():
mock_obj = Mock()
mock_obj.existing_attr = "value"
# Seal the mock
seal(mock_obj)
# Existing attributes still work
assert mock_obj.existing_attr == "value"
# New attributes raise AttributeError
try:
_ = mock_obj.new_attr
assert False, "Should have raised AttributeError"
except AttributeError:
pass # Expected
# Sealing prevents typos in tests
def test_seal_prevents_typos():
mock_service = Mock()
mock_service.process_data = Mock(return_value="result")
seal(mock_service)
# This works
result = mock_service.process_data("input")
assert result == "result"
# This would catch typos at runtime
try:
mock_service.proces_data("input") # Typo in method name
assert False, "Should catch typo"
except AttributeError:
pass # Typo caught
# Sealing with autospec
def test_seal_with_autospec():
from mock import create_autospec
class Service:
def method_one(self): pass
def method_two(self): pass
mock_service = create_autospec(Service)
seal(mock_service)
# Spec methods work
mock_service.method_one.return_value = "one"
mock_service.method_two.return_value = "two"
# Non-spec methods raise AttributeError
try:
mock_service.method_three()
assert False, "Should not allow non-spec method"
except AttributeError:
passCreate unique sentinel values for testing.
# Sentinel factory
sentinel: object # Factory for creating unique sentinel objects
# Individual sentinel object
class _SentinelObject:
def __init__(self, name: str) -> None: ...
name: str
# Usage: sentinel.ATTRIBUTE_NAME creates unique sentinelUsage examples:
from mock import sentinel
# Create unique sentinels
MISSING = sentinel.MISSING
EMPTY = sentinel.EMPTY
DEFAULT_VALUE = sentinel.DEFAULT_VALUE
def process_value(value=MISSING):
if value is MISSING:
return "no value provided"
elif value is EMPTY:
return "empty value"
else:
return f"value: {value}"
# Test with sentinels
def test_with_sentinels():
assert process_value() == "no value provided"
assert process_value(EMPTY) == "empty value"
assert process_value("real") == "value: real"
# Sentinels are unique
assert MISSING is not EMPTY
assert MISSING is not DEFAULT_VALUE
assert EMPTY is not DEFAULT_VALUE
# But same name creates same sentinel
assert sentinel.MISSING is MISSING# Match any value in assertions
ANY: object # Always equals any other object
# Default value marker
DEFAULT: object # Marker for default behavior in mocksUsage examples:
from mock import Mock, ANY, DEFAULT, call
# ANY matches anything
def test_any_matching():
mock_func = Mock()
mock_func("arg1", "arg2")
# These all pass
mock_func.assert_called_with("arg1", ANY)
mock_func.assert_called_with(ANY, "arg2")
mock_func.assert_called_with(ANY, ANY)
# ANY in call lists
def test_any_in_calls():
mock_func = Mock()
mock_func("first", 1)
mock_func("second", 2)
expected_calls = [
call("first", ANY),
call(ANY, 2)
]
mock_func.assert_has_calls(expected_calls)
# DEFAULT in side effects
def test_default_marker():
mock_func = Mock()
mock_func.side_effect = ["first", DEFAULT, "third"]
mock_func.return_value = "default_return"
assert mock_func() == "first"
assert mock_func() == "default_return" # DEFAULT uses return_value
assert mock_func() == "third"# Utility type definitions
class _SpecState:
"""Internal state for spec-based mocks."""
spec: Any
ids: Any
spec_set: Any
parent: Any
instance: Any
name: Any
class InvalidSpecError(Exception):
"""Raised when spec validation fails."""Install with Tessl CLI
npx tessl i tessl/pypi-types-mock