Labs ICT
โญ Pro Login

Mocking with monkeypatch & unittest.mock

Replacing parts of your system for isolated testing.

Mocking and Patching

Mocking replaces parts of your system with fake objects during testing. This isolates your tests from external dependencies like databases, APIs, or file systems.

monkeypatch Fixture

pytest's built-in monkeypatch fixture modifies objects, attributes, and environment variables safely:

import os

def get_api_url():
    return os.environ.get("API_URL", "http://localhost:8000")

def test_custom_api_url(monkeypatch):
    monkeypatch.setenv("API_URL", "http://staging.example.com")
    assert get_api_url() == "http://staging.example.com"

def test_default_api_url(monkeypatch):
    monkeypatch.delenv("API_URL", raising=False)
    assert get_api_url() == "http://localhost:8000"

Patching Functions

Use monkeypatch.setattr to replace function implementations:

import datetime

def get_today():
    return datetime.date.today()

def test_specific_date(monkeypatch):
    class FakeDate:
        @staticmethod
        def today():
            return datetime.date(2025, 1, 1)

    monkeypatch.setattr(datetime, "date", FakeDate)
    assert get_today() == datetime.date(2025, 1, 1)

unittest.mock

For more complex scenarios, use Python's unittest.mock module alongside pytest:

from unittest.mock import Mock, patch

def test_api_call():
    with patch("my_module.requests.get") as mock_get:
        mock_get.return_value.status_code = 200
        mock_get.return_value.json.return_value = {"result": "ok"}

        response = fetch_data()
        assert response == {"result": "ok"}
        mock_get.assert_called_once_with("https://api.example.com")

Mock Best Practices

  • Mock at the boundary - mock external services, not internal logic.
  • Keep mocks simple - verify behavior, not implementation details.
  • Use monkeypatch for simple replacements, unittest.mock for complex ones.
  • Always prefer real objects when they are fast and deterministic.

๐Ÿงช Quick Quiz

What is monkeypatch used for in pytest?