Understanding Mock and MagicMock in Python

This article was written so anyone can understand it (if there is anything unclear, let me know so it can be improved), even if you are just getting started with testing in Python.

We will explain what each concept is, why it exists, and when to use it, always with practical examples and clear explanations.


1. What is a Mock? (simple explanation)

A Mock is a fake object, created only for tests, that pretends to be a real object.

It allows you to:

Instead of using:

we use a mock to simulate this behavior.

Why is this important?

Because in tests we want:

Mental example

Imagine a function that sends emails:

PYTHON
def send_email(to):
    print("Sending email")
Click to expand and view more

In a test, you do not want to send real emails. So you replace this function with a mock.

The mock:

👉 That is why we say a mock is flexible: you define how it should behave.

👉 Any attribute accessed on a Mock automatically becomes another Mock.


2. What is MagicMock?

MagicMock is a special type and subclass of Mock.

It exists to simulate objects that use Python magic methods.

What are magic methods?

They are methods that:

Common examples:

These methods are not called directly, but by Python itself.

Why does MagicMock exist?

A regular Mock does not handle these methods well. MagicMock is already prepared for them.


3. Mock ≠ Stub ≠ Fake (important differences)

Stub

A stub only returns fixed values.

PYTHON
def get_user_stub():
    return {"id": 1}
Click to expand and view more

Fake

A fake has a simple but functional implementation.

PYTHON
class FakeEmailService:
    def __init__(self):
        self.sent = []

    def send(self, to):
        self.sent.append(to)
Click to expand and view more

Mock

A mock records calls and validates interactions.

PYTHON
from unittest.mock import Mock

email = Mock()
email.send("a@test.com")
email.send.assert_called_once_with("a@test.com")
Click to expand and view more

4. Main attributes and methods

return_value

Defines the value returned by the mock.

PYTHON
mock.func.return_value = 10
Click to expand and view more

side_effect

Allows exceptions, functions, or multiple return values.

PYTHON
mock.func.side_effect = Exception("Error")
Click to expand and view more

called / call_count

Indicate whether and how many times it was called.

PYTHON
assert mock.func.called
assert mock.func.call_count == 1
Click to expand and view more

call_args / call_args_list

Show the arguments used.

PYTHON
mock.func(1)
mock.func(2)

assert mock.func.call_args_list == [((1,),), ((2,),)]
Click to expand and view more

5. patch — replacing dependencies

Use patch to temporarily replace real dependencies with mocks.

Golden rule:

You must patch where the object is USED, not where it is DEFINED.

PYTHON
# app/services.py
from app.email import send_email

def notify(user):
    send_email(user.email)
Click to expand and view more
PYTHON
with patch("app.services.send_email") as mock_send:
    notify(user)
Click to expand and view more

❌ WRONG:

PYTHON
patch("app.email.send_email")
Click to expand and view more

6. spec and autospec

Use them to avoid silent errors and ensure correct signatures.

spec

Restricts valid attributes.

PYTHON
mock = Mock(spec=MyClass)
Click to expand and view more

autospec

Restricts attributes and the function signature.

PYTHON
@patch("module.func", autospec=True)
def test(mock_func):
    ...
Click to expand and view more

✅ Prevents silent errors.


7. Mock with logic → use Fake

If a mock contains complex logic, turn it into a fake.


8. Common problems and how to solve them

❌ Mock does not work

➡️ Patch applied in the wrong place

❌ Test passes but breaks in production

➡️ Missing autospec

❌ Test is hard to understand

➡️ Too many mocks

❌ Mock with logic

➡️ Extract into a fake


9. When to use (and when NOT to use)

Use mocks when:

Do NOT use mocks when:

Practical rule: mock dependencies, not business rules.


10. Real best practices


11. Anti-patterns

🚫 Mocking private methods
🚫 Mocking domain logic
🚫 Testing only calls
🚫 Excessive nested mocks


12. Mental checklist

Before creating a mock:


References

Copyright Notice

Link: https://alra.dev/posts/understanding-mock-and-magicmock-in-python/

License: 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议

本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。

Start searching

Enter keywords to search articles

↑↓
ESC
⌘K Shortcut