← Back to Python

Pytest — Fixtures, Mocking, Patching

PythonMidpythontesting

The Question

How do pytest fixtures, mocking, and patching work?

What a Strong Answer Covers

  • fixtures injected by name
  • "patch where used
  • "MagicMock

Senior-Level Answer

**Fixtures** are functions decorated with `@pytest.fixture` that pytest injects into test functions by parameter name. They handle setup and teardown via yield: code before yield runs before the test, code after yield runs after it regardless of outcome. Fixtures have scopes — function (default, re-created each test), class, module, session — that control how often the fixture is instantiated. Session-scoped fixtures are ideal for expensive resources like database connections. Fixtures can depend on other fixtures, letting you compose complex setups from small pieces. conftest.py files make fixtures available across a directory tree without explicit imports.

**Mocking** replaces real objects with `MagicMock` or `AsyncMock` instances that record calls and return configurable values. You create a mock, configure `mock.return_value` or `mock.side_effect`, pass it into the code under test, then assert on `mock.called`, `mock.call_args`, or `mock.call_count`.

**Patching** is how you inject mocks into code that creates its own dependencies internally. `unittest.mock.patch` temporarily replaces a name in a specific module's namespace. The key rule: patch where the name is looked up, not where it is defined. If `myapp.service` imports `requests` and uses `requests.get`, you patch `myapp.service.requests.get`, not `requests.get`.

patch can be used as a decorator, a context manager, or called manually with start/stop. The `pytest-mock` library exposes a `mocker` fixture that provides `mocker.patch()` with automatic teardown, which is cleaner than decorator stacking.

`side_effect` is more powerful than `return_value`: it can be a list of successive return values, an exception class to raise, or a callable that inspects arguments. Use side_effect when the mock needs to behave differently across calls or simulate failures.

For async code, use `AsyncMock` (Python 3.8+) so that awaiting the mock works correctly. A regular `MagicMock` used as a coroutine will raise a TypeError.

What Separates a 2/3 from a 3/3

2/3 — Passing but Incomplete

Explains fixtures with scope, uses patch correctly for a simple case, and knows the 'patch where imported' rule.

3/3 — Strong Answer

Articulates yield fixture teardown, compares mocker vs decorator stacking, explains side_effect vs return_value, and handles the async case.

Common Mistakes

  • Patching the definition location instead of the import location in the module under test
  • Using function-scope for expensive fixtures that should be session-scoped
  • Not using AsyncMock for coroutines — test passes but mock is never actually awaited
  • Overusing mocks — mocking so many dependencies that the test no longer covers meaningful behavior

Follow-Up Questions

  • How do you share a fixture across multiple test files? — Define it in conftest.py at the package root; pytest discovers it automatically.
  • What is the difference between patch and patch.object? — patch takes a dotted string; patch.object takes the actual object and an attribute name — useful when you have a direct reference.
  • How would you test a function that calls datetime.now() internally? — Patch datetime in the module under test, or inject a clock dependency for easier testing.
  • When should you prefer dependency injection over patching? — DI makes dependencies explicit and testable without import-path magic; patch is a workaround for code that creates its own dependencies.

Related Questions

  • GIL — What It Is and What It Protects
  • ThreadPoolExecutor & ProcessPoolExecutor
  • Decorators — Under the Hood
  • Generators & yield
  • Context Managers

Can You Explain This Cold?

Reading the answer is step one. Explaining it unprompted — under interview pressure — is what actually matters. Get AI-graded feedback on your answer with follow-up probes on your weak points.

Get Graded — Free Assessment
GrindQuestionsAITechnical interview assessment
TermsPrivacyAbout