Search the courses, subjects, tracks, games and features, or jump straight to a page.
Learn it your way
A short class with Sarah and her students. The other ways are under More.
Sign up free to listen. Transcripts are free to read.
Our get_temperature() function calls a weather API. What could go wrong if a unit test called the real API?
The network could be down, and the temperature changes all the time, so the test result would keep changing.
Exactly. Tests must be fast and repeatable. So we replace the real client with a mock, a fake object whose answers we control.
Do we have to write a fake class for every dependency?
No. unittest.mock.Mock creates one for us. Any attribute or method you ask it for simply exists, and you decide what it returns.
Look at mock_api.fetch_temperature.return_value = 30. What does it mean?
Whenever fetch_temperature is called on the mock, it returns 30?
Yes, whatever arguments are passed. So get_temperature(mock_api) returns 30, and the test can assert that.
But nothing was really fetched.
That's the point. We're testing our function's logic, not the weather service.
Getting 30 back isn't the whole story. How do we know our function asked for the right city?
Does the mock remember how it was called?
It does. mock_api.fetch_temperature.assert_called_once_with('Delhi') fails if it was called with another city, or not exactly once.
So a mock can check both what comes out and what went in.
Exactly. return_value controls the output, and assertions such as assert_called_once_with() check the interaction.
Replace external dependencies with mocks so a unit test checks only your own code.
Mock() creates attributes and methods on demand and records every call made to them.
Setting return_value fixes what a mocked method returns.
assert_called_once_with() verifies how many times a mock was called and with which arguments.
A function that receives its client as an argument, like get_temperature(api_client), is easy to test with a mock.
A mock records every call, so you can inspect its use afterwards with call_count and call_args_list:
from unittest.mock import Mock
mock_api = Mock()
mock_api.fetch_temperature.return_value = 30
print(mock_api.fetch_temperature("Delhi"))
print(mock_api.fetch_temperature("Mumbai"))
print("called", mock_api.fetch_temperature.call_count, "times")
print("calls:", mock_api.fetch_temperature.call_args_list)assert_called_once_with() catches a bug that the return value alone would hide, here a misspelt city name:
from unittest.mock import Mock
def get_temperature(api_client):
return api_client.fetch_temperature("Dehli") # typo in the city name
mock_api = Mock()
mock_api.fetch_temperature.return_value = 30
print(get_temperature(mock_api)) # still 30, so the result looks fine
try:
mock_api.fetch_temperature.assert_called_once_with("Delhi")
except AssertionError as e:
print("AssertionError:", e)Setting side_effect to an exception makes the mock raise it, so you can test how your code handles a failing API:
from unittest.mock import Mock
def get_temperature_or_none(api_client):
try:
return api_client.fetch_temperature("Delhi")
except ConnectionError:
return None
mock_api = Mock()
mock_api.fetch_temperature.side_effect = ConnectionError("network down")
print(get_temperature_or_none(mock_api))
mock_api.fetch_temperature.assert_called_once_with("Delhi")
print("the error was handled and the call was still checked")Mock the call and fix the reply; assert how it was called, and the test won't lie.
Ravi's team tested their checkout code against a fake payment gateway that always answered "approved". The tests ran in milliseconds and never charged a real card, and when the fake recorded two payment calls for a single order, they found a double-charge bug before any customer did.
"Replace, Return, Run, Assert": replace the dependency with Mock(), set its return_value, run your code, then assert the calls.
M.O.C.K. - Make a Mock, Override its return value, Call your code, Keep an eye on the calls with assertions.
Term
What does `Mock()` create?
Click to flip
Term
How do you make a mocked method return 30?
Click to flip
Term
Which assertion checks that a mock was called exactly once with given arguments?
Click to flip
Term
How do you make a mocked method raise an exception?
Click to flip
Term
Why are mocks used in unit tests?
Click to flip
Replacing a real object with a controllable fake during a test.
The unittest.mock class whose objects accept any attribute access or call and record how they were used.
The standard-library module that provides Mock, MagicMock and patch.
The attribute that sets what a mock returns when it is called.
A mock assertion that passes only if the mock was called exactly once with the given arguments.
A mock attribute that makes a call raise an exception, return values from a list in turn, or run a function.
An outside component your code relies on, such as an API client or a database.
Mocking replaces real objects with simulated ones to isolate code in unit testing. This lesson tests a weather function with unittest.mock.Mock instead of a real API.
In unit testing, mocks are used to replace real dependencies (like APIs or databases) with fake objects that return controlled responses. This allows tests to run quickly and deterministically, without relying on external systems.
Mocking is an essential testing technique that allows you to simulate parts of your program, especially external services or components that you don’t want to call during tests. Python provides the unittest.mock module to create and manage mock objects easily.
Example Scenario: Suppose you have a service that fetches the weather using an API. During testing, you want to avoid hitting the real API.
# weather_service.py
def get_temperature(api_client):
return api_client.fetch_temperature("Delhi")
# Trying it out with a hand-written stand-in for the API client
class StandInClient:
def fetch_temperature(self, city):
return 25
print(get_temperature(StandInClient()))Because get_temperature() receives the client as an argument, any object with a fetch_temperature() method will do. A hand-written stand-in works, but you would need a new class for every case. Mock builds such stand-ins for you and also records how they were used.
Now, to test this function without actually making a network call, use mocking:
# test_weather_service.py
# In the two-file project, this file starts by importing the function under test:
# from weather_service import get_temperature
# Here the function is repeated so that the block runs on its own.
from unittest.mock import Mock
def get_temperature(api_client):
return api_client.fetch_temperature("Delhi")
def test_get_temperature():
mock_api = Mock()
mock_api.fetch_temperature.return_value = 30
result = get_temperature(mock_api)
assert result == 30
mock_api.fetch_temperature.assert_called_once_with("Delhi")
test_get_temperature()
print("test_get_temperature passed")A test runner such as pytest finds and runs test_get_temperature() by itself; here it is called directly so you can see it pass.
Breakdown:
Mock() creates a fake object that mimics the API.return_value sets the result the mock should return.assert_called_once_with() verifies correct interaction.This is useful when the real service is slow, unreliable, or has side effects. Mocks allow you to write fast, reliable, and isolated tests.
Three quick questions to check your understanding. The Practice tab has more.
Question: Why do we use mocks in unit testing?
Answer: Mocks are used to simulate the behavior of external dependencies like APIs, databases, or file systems, enabling us to test our code in isolation without relying on those actual services.
Hint: Think about scenarios where real dependencies might fail, slow down, or behave unpredictably.
Question: What does the following code do?
from unittest.mock import Mock
mock_api = Mock()
mock_api.get_status.return_value = "OK"
print(mock_api.get_status())
print(mock_api.get_status("any", "arguments"))Answer: It creates a mock object with a method get_status that, when called, will always return "OK". This simulates a predictable response for testing.
Hint: Consider the method chaining and return value.
Question: How do you verify if a mock method was called with a specific argument?
Answer: Use mock_object.method.assert_called_once_with(arguments) to ensure the mock method was called exactly once with those arguments.
Hint: This is part of mock’s assertion methods.