Mocking external services helps you test your Django app without calling real outside systems. This makes tests faster and safer.
Mocking external services in Django
Start learning this pattern below
Jump into concepts and practice - no test required
or
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Introduction
Syntax
Django
from unittest.mock import patch @patch('path.to.external.service.function') def test_function(mock_function): mock_function.return_value = 'mocked response' # your test code here
Use @patch to replace the real function with a mock during the test.
Set return_value on the mock to control what it returns.
Examples
requests.get call to return a fake response with status 200 and a JSON body.Django
from unittest.mock import patch @patch('requests.get') def test_api_call(mock_get): mock_get.return_value.status_code = 200 mock_get.return_value.json.return_value = {'key': 'value'} response = requests.get('http://fakeapi.com') assert response.status_code == 200 assert response.json() == {'key': 'value'}
send_email function to always return True during the test.Django
from unittest.mock import patch @patch('myapp.services.send_email') def test_send_email(mock_send): mock_send.return_value = True result = send_email('test@example.com') assert result is True
Sample Program
This example shows how to mock the requests.get call inside the fetch_data function. The test replaces the real HTTP call with a mock that returns a fake JSON response. When run, it prints the mocked data.
Django
from unittest.mock import patch import requests def fetch_data(): response = requests.get('https://api.example.com/data') if response.status_code == 200: return response.json() return None @patch('requests.get') def test_fetch_data(mock_get): mock_get.return_value.status_code = 200 mock_get.return_value.json.return_value = {'name': 'Test'} data = fetch_data() print(data) if __name__ == '__main__': test_fetch_data()
Important Notes
Always patch the exact location where the function is used, not where it is defined.
Mocks help keep tests fast and independent from outside systems.
Summary
Mocking replaces real external calls with fake ones during tests.
Use @patch decorator from unittest.mock to mock functions.
Set return values on mocks to control test scenarios easily.
Practice
1. What is the main reason to use mocking for external services in Django tests?
easy
Solution
Step 1: Understand the purpose of mocking
Mocking replaces real external calls with fake ones to avoid delays and failures during tests.Step 2: Identify the benefit in testing context
By not making real network calls, tests run faster and are more reliable.Final Answer:
To avoid making real network calls during tests -> Option AQuick Check:
Mocking avoids real calls = A [OK]
Hint: Mock external calls to keep tests fast and reliable [OK]
Common Mistakes:
- Thinking mocking speeds up the server
- Confusing mocking with deployment
- Assuming mocking generates docs
2. Which of the following is the correct way to patch an external service call in a Django test using unittest.mock?
easy
Solution
Step 1: Understand patch target format
The patch decorator requires the full import path to the function or method to mock.Step 2: Match the correct import path
@patch('myapp.services.external_api_call') correctly specifies the module and function as 'myapp.services.external_api_call'.Final Answer:
@patch('myapp.services.external_api_call') -> Option DQuick Check:
Correct patch path = D [OK]
Hint: Patch using full import path of the function to mock [OK]
Common Mistakes:
- Reversing module and function order
- Using incomplete import paths
- Patching the wrong module
3. Given this test code snippet, what will be printed?
from unittest.mock import patch
def get_data():
return external_service_call()
@patch('myapp.services.external_service_call')
def test_get_data(mock_call):
mock_call.return_value = {'status': 'ok'}
result = get_data()
print(result)medium
Solution
Step 1: Understand patch effect on external_service_call
The patch replaces external_service_call with a mock that returns {'status': 'ok'} only inside the decorated function test_get_data.Step 2: Analyze get_data call outside patch scope
get_data() calls external_service_call(), but external_service_call is not defined globally, leading to a NameError.Final Answer:
Error: external_service_call not defined -> Option AQuick Check:
external_service_call undefined outside patch = D [OK]
Hint: Patch only affects references inside the decorated function [OK]
Common Mistakes:
- Assuming patch affects global scope
- Expecting mock return_value outside patch
- Ignoring NameError due to missing definition
4. What is wrong with this test code that tries to mock an external API call?
from unittest.mock import patch
def test_api_call():
with patch('myapp.services.external_api_call') as mock_call:
mock_call.return_value = {'success': True}
result = external_api_call()
print(result)medium
Solution
Step 1: Check patch context usage
The patch is applied only inside the with block, but external_api_call is called after it ends.Step 2: Understand effect on mocking
Since external_api_call is called outside the patch block, it is not mocked and runs the real function.Final Answer:
The patch context ends before calling external_api_call -> Option BQuick Check:
Call must be inside patch block = C [OK]
Hint: Call mocked function inside patch block or decorator [OK]
Common Mistakes:
- Calling function outside patch context
- Setting return_value too late
- Assuming patch works globally without context
5. You want to test a Django view that calls an external payment API. Which approach correctly mocks the external call and verifies the view handles a failure response gracefully?
from unittest.mock import patch
from django.test import Client
@patch('payments.api.call_payment')
def test_payment_failure(mock_call):
mock_call.return_value = {'status': 'error', 'code': 500}
client = Client()
response = client.post('/pay/')
print(response.status_code)
What should you add to the test to check the view's behavior?hard
Solution
Step 1: Understand mocking external payment API
The patch replaces call_payment with a mock returning an error response.Step 2: Verify view handles error but returns HTTP 200
The view should catch the error and respond with HTTP 200 (page loads with error message), not propagate 500.Step 3: Check mock call was made
Asserting mock_call was called confirms the external API was invoked in the view.Final Answer:
Assert mock_call was called once and response.status_code is 200 -> Option CQuick Check:
Mock call checked + 200 response = B [OK]
Hint: Check mock call and expect view to handle errors with 200 [OK]
Common Mistakes:
- Expecting 500 status from view on API error
- Not asserting mock call was made
- Removing patch and making real calls
