CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-mock

Rolling backport of unittest.mock for all Pythons

Pending
Overview
Eval results
Files

special-objects.mddocs/

Special Objects

The mock library provides several special objects and constants for flexible mock assertions, unique object creation, and advanced testing patterns.

Capabilities

ANY

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: _ANY

call

A 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: _Call

sentinel

A 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: _Sentinel

DEFAULT

A special sentinel value used to represent default behavior in mock side_effect and return_value.

DEFAULT: object  # Special sentinel for default mock behavior

FILTER_DIR

A boolean constant that controls whether dir() filtering is applied to mock objects.

FILTER_DIR: bool  # Controls dir() filtering on mocks

InvalidSpecError

Exception 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.
    """

Usage Patterns

Using ANY in Assertions

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 args

ANY with Complex Objects

from 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)

Using call Objects

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)

Call Objects for Direct Function Calls

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)

Using sentinel Objects

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'

Sentinel for Mock Configuration

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 != result2

Using DEFAULT with side_effect

from 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'

Complex Assertion Patterns

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)

Combining Special Objects

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)

FILTER_DIR Usage

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_filter

Install with Tessl CLI

npx tessl i tessl/pypi-mock

docs

index.md

mock-objects.md

patching.md

special-objects.md

utilities.md

tile.json