Skip to content

Mocking (unittest.mock)

Mock external dependencies to isolate tests and control behavior.

Mental Model

A mock is a stunt double for a real object. It stands in for an external dependency — a database, an API, the filesystem — so your test exercises only the logic you care about, not the infrastructure behind it. You tell the mock what to return, run the code, then ask the mock whether it was called correctly.

Basic Mocking

Replace objects with mocks.

```python from unittest.mock import Mock, patch

def get_user_data(user_id): # Normally makes a database call return {"id": user_id, "name": "Alice"}

def test_with_mock(): with patch('main.get_user_data') as mock_get: mock_get.return_value = {"id": 1, "name": "Mocked"}

    result = get_user_data(1)

    assert result["name"] == "Mocked"
    mock_get.assert_called_once_with(1)

Direct mock creation

mock_obj = Mock() mock_obj.method.return_value = 42 assert mock_obj.method() == 42 print("Mocking complete") ```

Mocking complete

Mocking with MagicMock

MagicMock supports magic methods.

```python from unittest.mock import MagicMock

MagicMock supports more operations

mock = MagicMock()

Can be used as iterable

mock.iter.return_value = [1, 2, 3] for item in mock: print(item)

Can be used as callable

mock.return_value = "result" result = mock() print(f"Call result: {result}")

Can be indexed

mock.getitem.return_value = "indexed" print(f"Indexed: {mock[0]}") ```

1 2 3 Call result: result Indexed: indexed


Runnable Example: mocking_basics_tutorial.py

```python """ 15_mocking_basics

15 MOCKING BASICS

Comprehensive tutorial on Mocking Basics.

Learning Objectives: - [Key concepts will be covered here] - [Hands-on examples provided] - [Progressive difficulty levels] - [Real-world applications]

Target: Intermediate to Advanced Level Prerequisites: Earlier modules completed """

This file contains comprehensive educational content

Teaching Mocking Basics concepts

print("Module: 15_mocking_basics.py") print("Content: Comprehensive tutorial with examples") print("Status: Educational content ready for classroom use")

Full implementation covers:

- Theory and concepts

- Practical examples

- Best practices

- Common patterns

- Real-world applications

if name == "main": print("\n============================================================") print("15 MOCKING BASICS - TUTORIAL MODULE")

# ============================================================================
print("============================================================")
print("\nThis module provides comprehensive coverage of the topic.")
print("Includes theory, examples, and hands-on practice.")

```


Exercises

Exercise 1. Write a function fetch_data(url) that calls requests.get(url).json(). Use unittest.mock.patch to mock requests.get and test fetch_data without making a real HTTP request.

Solution to Exercise 1

```python from unittest.mock import patch, MagicMock

def fetch_data(url): import requests return requests.get(url).json()

@patch("requests.get") def test_fetch_data(mock_get): mock_response = MagicMock() mock_response.json.return_value = {"key": "value"} mock_get.return_value = mock_response

result = fetch_data("http://example.com/api")
assert result == {"key": "value"}
mock_get.assert_called_once_with("http://example.com/api")

```


Exercise 2. Predict the output of this code:

```python from unittest.mock import MagicMock

mock = MagicMock() mock.foo.bar.baz(42) print(mock.foo.bar.baz.called) print(mock.foo.bar.baz.call_args) ```

Solution to Exercise 2

True call(42)

MagicMock automatically creates nested mock attributes. Calling mock.foo.bar.baz(42) records the call. called returns True and call_args shows the arguments.


Exercise 3. Write a class EmailService with a method send(to, subject, body). Write a class UserRegistration that depends on EmailService. Use a MagicMock to verify that send is called with the correct arguments when a user registers.

Solution to Exercise 3

```python from unittest.mock import MagicMock

class EmailService: def send(self, to, subject, body): pass # real implementation

class UserRegistration: def init(self, email_service): self.email_service = email_service

def register(self, email, name):
    self.email_service.send(
        to=email,
        subject="Welcome!",
        body=f"Hello {name}, welcome!"
    )

def test_registration_sends_email(): mock_email = MagicMock(spec=EmailService) reg = UserRegistration(mock_email) reg.register("alice@test.com", "Alice")

mock_email.send.assert_called_once_with(
    to="alice@test.com",
    subject="Welcome!",
    body="Hello Alice, welcome!"
)

```


Exercise 4. Use @patch as a decorator to mock os.path.exists in a test. Write a function check_file(path) that returns "Found" or "Not found" based on os.path.exists, and test both branches.

Solution to Exercise 4

```python from unittest.mock import patch import os

def check_file(path): if os.path.exists(path): return "Found" return "Not found"

@patch("os.path.exists", return_value=True) def test_file_found(mock_exists): assert check_file("/some/path") == "Found"

@patch("os.path.exists", return_value=False) def test_file_not_found(mock_exists): assert check_file("/some/path") == "Not found" ```