skills/bossjones/pytest-mock-guide/SKILL.md
Guide for using pytest-mock plugin to write tests with mocking. Use when writing pytest tests that need mocking, patching, spying, or stubbing. Covers mocker fixture usage, patch methods, spy/stub patterns, and assertion helpers.
npx skillsauth add aiskillstore/marketplace pytest-mock-guideInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
pytest-mock is a pytest plugin providing a mocker fixture as a thin wrapper around Python's unittest.mock patching API. It automatically undoes all mocking at the end of each test.
The mocker fixture is the main interface. Request it in your test function:
def test_example(mocker):
# All mocks are automatically cleaned up after this test
mock_func = mocker.patch("module.function")
| Fixture | Scope | Use Case |
|---------|-------|----------|
| mocker | function | Default, per-test mocking |
| class_mocker | class | Share mocks across test class |
| module_mocker | module | Share mocks across test module |
| package_mocker | package | Share mocks across package |
| session_mocker | session | Share mocks across entire session |
Patch a module-level object by its dotted path:
def test_patch(mocker):
# Patch os.remove function
mock_remove = mocker.patch("os.remove")
mock_remove.return_value = None
os.remove("file.txt")
mock_remove.assert_called_once_with("file.txt")
Patch an attribute on an object directly:
def test_patch_object(mocker):
import os
mock_remove = mocker.patch.object(os, "remove")
os.remove("file.txt")
mock_remove.assert_called_once_with("file.txt")
Patch a dictionary temporarily:
def test_patch_dict(mocker):
config = {"debug": False}
mocker.patch.dict(config, {"debug": True})
assert config["debug"] is True
# After test, config["debug"] is False again
Patch multiple attributes at once:
def test_patch_multiple(mocker):
mocks = mocker.patch.multiple(
"os",
remove=mocker.DEFAULT,
listdir=mocker.DEFAULT
)
os.remove("file.txt")
os.listdir("/tmp")
mocks["remove"].assert_called_once()
mocks["listdir"].assert_called_once()
Same as patch.object but doesn't warn when mock is used as context manager:
def test_context_manager(mocker):
mock_open = mocker.patch.context_manager(builtins, "open")
# No warning when using `with mock_open(...)`
| Parameter | Description |
|-----------|-------------|
| new | Object to replace target with |
| return_value | Value returned when mock is called |
| side_effect | Exception to raise or function to call |
| autospec | Create mock matching target's signature |
| spec | Object to use as specification |
| spec_set | Stricter spec that prevents setting new attributes |
| create | Allow patching non-existent attributes |
| new_callable | Callable to create the mock |
Spy wraps the real method while tracking calls:
def test_spy(mocker):
spy = mocker.spy(os.path, "exists")
# Real method is called
result = os.path.exists("/tmp")
# But we can inspect calls
spy.assert_called_once_with("/tmp")
# Access return values
assert spy.spy_return == result
assert spy.spy_return_list == [result] # All returns
| Attribute | Description |
|-----------|-------------|
| spy_return | Last return value from real method |
| spy_return_list | List of all return values |
| spy_return_iter | Iterator copy (when duplicate_iterators=True) |
| spy_exception | Last exception raised, if any |
def test_spy_iterator(mocker):
spy = mocker.spy(obj, "get_items", duplicate_iterators=True)
items = list(obj.get_items())
# Access a copy of the returned iterator
spy_items = list(spy.spy_return_iter)
Create a stub that accepts any arguments:
def test_stub(mocker):
callback = mocker.stub(name="my_callback")
some_function(on_complete=callback)
callback.assert_called_once()
Create an async stub:
async def test_async_stub(mocker):
callback = mocker.async_stub(name="async_callback")
await some_async_function(on_complete=callback)
callback.assert_awaited_once()
Create a mock that matches the spec's signature:
def test_autospec(mocker):
mock_obj = mocker.create_autospec(MyClass, instance=True)
# Calling with wrong arguments raises TypeError
mock_obj.method() # OK if method() takes no args
Access mock classes directly through mocker:
def test_mock_classes(mocker):
mock = mocker.Mock()
magic_mock = mocker.MagicMock()
async_mock = mocker.AsyncMock()
property_mock = mocker.PropertyMock()
non_callable = mocker.NonCallableMock()
def test_utilities(mocker):
# Match any argument
mock.assert_called_with(mocker.ANY)
# Create call objects for assertion
mock.assert_has_calls([mocker.call(1), mocker.call(2)])
# Sentinel objects
result = mocker.sentinel.my_result
# Mock file open
m = mocker.mock_open(read_data="file contents")
mocker.patch("builtins.open", m)
# Seal a mock to prevent new attributes
mocker.seal(mock)
Stop all patches immediately:
def test_stopall(mocker):
mocker.patch("os.remove")
mocker.patch("os.listdir")
mocker.stopall() # Both patches stopped
Stop a specific patch:
def test_stop(mocker):
mock_remove = mocker.patch("os.remove")
mocker.stop(mock_remove) # Only this patch stopped
Reset all mocks without stopping them:
def test_resetall(mocker):
mock_func = mocker.patch("module.func")
mock_func("arg1")
mocker.resetall()
mock_func.assert_not_called() # Call history cleared
pytest-mock enhances assertion error messages with pytest's comparison:
def test_assertions(mocker):
mock = mocker.patch("module.func")
mock("actual_arg")
# Enhanced error shows diff between expected and actual
mock.assert_called_with("expected_arg")
# AssertionError shows:
# Args:
# assert ('actual_arg',) == ('expected_arg',)
Call Assertions:
assert_called() - Called at least onceassert_called_once() - Called exactly onceassert_called_with(*args, **kwargs) - Last call matchesassert_called_once_with(*args, **kwargs) - Called once with argsassert_any_call(*args, **kwargs) - Any call matchesassert_has_calls(calls, any_order=False) - Has specific callsassert_not_called() - Never calledAsync Assertions (for AsyncMock):
assert_awaited()assert_awaited_once()assert_awaited_with(*args, **kwargs)assert_awaited_once_with(*args, **kwargs)assert_any_await(*args, **kwargs)assert_has_awaits(calls, any_order=False)assert_not_awaited()In pytest.ini, pyproject.toml, or setup.cfg:
[pytest]
# Enable/disable enhanced assertion messages (default: true)
mock_traceback_monkeypatch = true
# Use standalone mock package instead of unittest.mock (default: false)
mock_use_standalone_module = false
# my_module.py
from os.path import exists
def check_file(path):
return exists(path)
# test_my_module.py
def test_check_file(mocker):
# Patch where it's used, not where it's defined
mocker.patch("my_module.exists", return_value=True)
assert check_file("/any/path") is True
def test_exception(mocker):
mock_func = mocker.patch("module.func")
mock_func.side_effect = ValueError("error message")
with pytest.raises(ValueError, match="error message"):
module.func()
def test_multiple_returns(mocker):
mock_func = mocker.patch("module.func")
mock_func.side_effect = [1, 2, 3]
assert module.func() == 1
assert module.func() == 2
assert module.func() == 3
async def test_async(mocker):
mock_fetch = mocker.patch("module.fetch_data")
mock_fetch.return_value = {"data": "value"}
result = await module.fetch_data()
assert result == {"data": "value"}
def test_class_method(mocker):
mocker.patch.object(MyClass, "class_method", return_value="mocked")
assert MyClass.class_method() == "mocked"
def test_property(mocker):
mock_prop = mocker.patch.object(
MyClass, "my_property",
new_callable=mocker.PropertyMock,
return_value="mocked"
)
obj = MyClass()
assert obj.my_property == "mocked"
development
Apple Human Interface Guidelines for content display components. Use this skill when the user asks about charts component, collection view, image view, web view, color well, image well, activity view, lockup, data visualization, content display, displaying images, rendering web content, color pickers, or presenting collections of items in Apple apps. Also use when the user says how should I display charts, what's the best way to show images, should I use a web view, how do I build a grid of items, what component shows media, or how do I present a share sheet. Cross-references: hig-foundations for color/typography/accessibility, hig-patterns for data visualization patterns, hig-components-layout for structural containers, hig-platforms for platform-specific component behavior.
tools
Automate HelpDesk tasks via Rube MCP (Composio): list tickets, manage views, use canned responses, and configure custom fields. Always search tools first for current schemas.
testing
Expert Haskell engineer specializing in advanced type systems, pure functional design, and high-reliability software. Use PROACTIVELY for type-level programming, concurrency, and architecture guidance.
tools
GraphQL gives clients exactly the data they need - no more, no less. One endpoint, typed schema, introspection. But the flexibility that makes it powerful also makes it dangerous. Without proper controls, clients can craft queries that bring down your server. This skill covers schema design, resolvers, DataLoader for N+1 prevention, federation for microservices, and client integration with Apollo/urql. Key insight: GraphQL is a contract. The schema is the API documentation. Design it carefully.