CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-pytest-mock

Thin-wrapper around the mock package for easier use with pytest

Pending
Overview
Eval results
Files

core-mocking.mddocs/

Core Mocking Operations

Essential mocking functionality for patching functions, methods, and objects. These operations form the foundation of test mocking in pytest-mock, providing the primary interface for replacing real code with mock objects during testing.

Capabilities

Function and Method Patching

Patches functions and methods with mock objects, allowing you to control their behavior and verify their usage during tests.

def patch(
    self,
    target: str,
    new: object = DEFAULT,
    spec: Optional[object] = None,
    create: bool = False,
    spec_set: Optional[object] = None,
    autospec: Optional[object] = None,
    new_callable: Optional[Callable] = None,
    **kwargs: Any
) -> MockType:
    """
    Patch a function or method with a mock object.
    
    Parameters:
    - target: String path to the target to patch (e.g., 'os.remove', 'mymodule.function')
    - new: Object to replace the target with (defaults to MagicMock)
    - spec: Object to use as template for mock attributes
    - create: Create attribute if it doesn't exist on target
    - spec_set: Stricter version of spec - only allows existing attributes
    - autospec: Automatically create spec from target object
    - new_callable: Factory function to create replacement object
    
    Returns:
    Mock object that replaced the target
    """

Usage examples:

def test_basic_patch(mocker):
    # Patch with default MagicMock
    mock_remove = mocker.patch('os.remove')
    mock_remove.return_value = None
    
    # Your code that calls os.remove
    delete_file('test.txt')
    
    mock_remove.assert_called_once_with('test.txt')

def test_patch_with_return_value(mocker):
    # Patch with specific return value
    mocker.patch('requests.get', return_value=mock_response)
    
    result = fetch_data('http://api.example.com')
    assert result == expected_data

def test_patch_with_autospec(mocker):
    # Create mock that matches the original function signature
    mocker.patch('mymodule.complex_function', autospec=True)
    
    # Mock will enforce correct number/types of arguments
    mymodule.complex_function('arg1', kwarg='value')

Object Attribute Patching

Patches specific attributes on objects, allowing targeted mocking of methods, properties, and class attributes.

def object(
    self,
    target: object,
    attribute: str,
    new: object = DEFAULT,
    spec: Optional[object] = None,
    create: bool = False,
    spec_set: Optional[object] = None,
    autospec: Optional[object] = None,
    new_callable: object = None,
    **kwargs: Any
) -> MockType:
    """
    Patch an attribute on an object with a mock.
    
    Parameters:
    - target: Object to patch
    - attribute: Name of attribute to patch
    - new: Object to replace the attribute with
    - spec: Object to use as template for mock attributes
    - create: Create attribute if it doesn't exist
    - spec_set: Stricter version of spec
    - autospec: Automatically create spec from original attribute
    - new_callable: Factory function to create replacement
    
    Returns:
    Mock object that replaced the attribute
    """

Usage examples:

def test_patch_method(mocker):
    # Patch a method on a class
    mock_send = mocker.patch.object(EmailClient, 'send')
    mock_send.return_value = True
    
    client = EmailClient()
    result = client.send('test@example.com', 'Hello')
    
    assert result is True
    mock_send.assert_called_once_with('test@example.com', 'Hello')

def test_patch_instance_method(mocker):
    # Patch method on specific instance
    client = EmailClient()
    mocker.patch.object(client, 'send', return_value=False)
    
    result = client.send('test@example.com', 'Hello')
    assert result is False

Context Manager Patching

Special patching for context managers that suppresses the context manager warning typically shown by pytest-mock.

def context_manager(
    self,
    target: object,
    attribute: str,
    new: object = DEFAULT,
    spec: Optional[object] = None,
    create: bool = False,
    spec_set: Optional[object] = None,
    autospec: Optional[object] = None,
    new_callable: object = None,
    **kwargs: Any
) -> MockType:
    """
    Patch an attribute without issuing context manager warnings.
    
    This is equivalent to patch.object except the returned mock
    does not issue a warning when used as a context manager.
    
    Parameters: Same as patch.object
    
    Returns:
    Mock object that replaced the attribute
    """

Usage example:

def test_context_manager_mock(mocker):
    # Mock a context manager without warnings
    mock_file = mocker.context_manager(builtins, 'open')
    mock_file.return_value.__enter__.return_value.read.return_value = 'content'
    
    with open('file.txt') as f:
        content = f.read()
    
    assert content == 'content'

Multiple Attribute Patching

Patches multiple attributes on a single object simultaneously, useful for comprehensive mocking of complex objects.

def multiple(
    self,
    target: object,
    spec: Optional[object] = None,
    create: bool = False,
    spec_set: Optional[object] = None,
    autospec: Optional[object] = None,
    new_callable: Optional[object] = None,
    **kwargs: Any
) -> Dict[str, MockType]:
    """
    Patch multiple attributes on a target object.
    
    Parameters:
    - target: Object to patch
    - spec: Object to use as template for all mocks
    - create: Create attributes if they don't exist
    - spec_set: Stricter version of spec
    - autospec: Automatically create specs
    - new_callable: Factory function for all replacements
    - **kwargs: attribute_name=replacement_value pairs
    
    Returns:
    Dictionary mapping attribute names to their mock objects
    """

Usage example:

def test_multiple_patches(mocker):
    # Patch multiple methods at once
    mocks = mocker.patch.multiple(
        EmailClient,
        send=mocker.DEFAULT,
        connect=mocker.DEFAULT,
        disconnect=mocker.DEFAULT
    )
    
    # Configure individual mocks
    mocks['send'].return_value = True
    mocks['connect'].return_value = 'connected'
    
    client = EmailClient()
    client.connect()
    result = client.send('test@example.com', 'Hello')
    client.disconnect()
    
    mocks['connect'].assert_called_once()
    mocks['send'].assert_called_once()
    mocks['disconnect'].assert_called_once()

Dictionary Patching

Patches dictionary entries, allowing you to mock configuration, environment variables, and other dictionary-based data.

def dict(
    self,
    in_dict: Union[Mapping[Any, Any], str],
    values: Union[Mapping[Any, Any], Iterable[Tuple[Any, Any]]] = (),
    clear: bool = False,
    **kwargs: Any
) -> Any:
    """
    Patch dictionary entries.
    
    Parameters:
    - in_dict: Dictionary to patch, or string name for module attribute
    - values: Dictionary of key-value pairs to set, or iterable of (key, value) tuples
    - clear: Remove all existing entries before applying patches
    - **kwargs: Additional key-value pairs to set
    
    Returns:
    The patched dictionary
    """

Usage examples:

def test_environment_variables(mocker):
    # Mock environment variables
    mocker.patch.dict('os.environ', {'API_KEY': 'test-key', 'DEBUG': 'true'})
    
    # Your code that reads environment variables
    api_key = get_api_key()  # reads os.environ['API_KEY']
    
    assert api_key == 'test-key'

def test_config_dict(mocker):
    # Mock application configuration
    test_config = {'database_url': 'sqlite:///:memory:', 'debug': True}
    mocker.patch.dict(app.config, test_config, clear=True)
    
    # Test code that uses app.config
    setup_database()
    assert app.config['database_url'] == 'sqlite:///:memory:'

Mock Lifecycle Management

Control and cleanup mock objects to ensure tests don't interfere with each other.

def resetall(
    self, 
    *, 
    return_value: bool = False, 
    side_effect: bool = False
) -> None:
    """
    Reset all mocks created by this fixture.
    
    Parameters:
    - return_value: Also reset return_value of mocks
    - side_effect: Also reset side_effect of mocks
    """

def stopall(self) -> None:
    """
    Stop all patches created by this fixture.
    Can be safely called multiple times.
    """

def stop(self, mock: unittest.mock.MagicMock) -> None:
    """
    Stop a specific patch by its mock object.
    
    Parameters:
    - mock: The mock object returned by a patch operation
    """

Usage examples:

def test_manual_reset(mocker):
    mock_func = mocker.patch('mymodule.function')
    mock_func.return_value = 'first'
    
    # Call and verify
    assert mymodule.function() == 'first'
    mock_func.assert_called_once()
    
    # Reset the mock
    mocker.resetall()
    
    # Mock state is reset
    assert mock_func.call_count == 0
    mock_func.return_value = 'second'
    assert mymodule.function() == 'second'

def test_manual_stop(mocker):
    mock_func = mocker.patch('mymodule.function')
    
    # Use the mock
    mymodule.function()
    
    # Stop this specific patch early
    mocker.stop(mock_func)
    
    # Function is back to normal
    result = mymodule.function()  # Calls real function

Install with Tessl CLI

npx tessl i tessl/pypi-pytest-mock

docs

core-mocking.md

fixtures.md

index.md

mock-creation.md

tile.json