Bird
Raised Fist0
Djangoframework~8 mins

Mocking external services in Django - Performance & Optimization

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Performance: Mocking external services
MEDIUM IMPACT
This concept affects page load speed and interaction responsiveness by avoiding real network calls during testing or development.
Testing or developing features that rely on external APIs
Django
from unittest.mock import patch

@patch('requests.get')
def test_get_data(mock_get):
    mock_get.return_value.json.return_value = {'key': 'value'}
    data = get_data()
    assert data['key'] == 'value'
Mocks network calls to return instant responses, eliminating network delays and improving test speed.
📈 Performance GainReduces network wait time to near zero, improving INP and developer feedback loop.
Testing or developing features that rely on external APIs
Django
import requests

def get_data():
    response = requests.get('https://api.example.com/data')
    return response.json()
This makes real network calls every time, causing slow tests and possible flakiness due to network issues.
📉 Performance CostBlocks test execution for network latency (100-500ms+ per call), increasing INP during development.
Performance Comparison
PatternNetwork CallsTest SpeedInteraction DelayVerdict
Real external service callsMultiple real HTTP requestsSlow due to network latencyHigh delay causing slow INP[X] Bad
Mocked external service callsNo real HTTP requestsFast with instant responsesMinimal delay, fast INP[OK] Good
Rendering Pipeline
Mocking external services bypasses the network request stage, so the browser or server does not wait for external responses, speeding up rendering and interaction.
Network Request
JavaScript Execution
Interaction Responsiveness
⚠️ BottleneckNetwork Request stage is the most expensive when calling real external services.
Core Web Vital Affected
INP
This concept affects page load speed and interaction responsiveness by avoiding real network calls during testing or development.
Optimization Tips
1Always mock external services in tests to avoid network delays.
2Use lightweight mocks to keep tests fast and reliable.
3Check DevTools Network tab to confirm no real HTTP calls during tests.
Performance Quiz - 3 Questions
Test your performance knowledge
Why is mocking external services beneficial for test performance?
AIt makes tests slower by adding extra code.
BIt increases the number of HTTP requests for better coverage.
CIt eliminates network latency by avoiding real HTTP calls.
DIt reduces CPU usage by skipping tests.
DevTools: Network
How to check: Open DevTools, go to the Network tab, run your tests or app, and observe if HTTP requests to external services are made.
What to look for: No external HTTP requests during tests means mocks are working; many requests indicate real calls causing delays.

Practice

(1/5)
1. What is the main reason to use mocking for external services in Django tests?
easy
A. To avoid making real network calls during tests
B. To speed up the Django development server
C. To automatically generate API documentation
D. To deploy the Django app faster

Solution

  1. Step 1: Understand the purpose of mocking

    Mocking replaces real external calls with fake ones to avoid delays and failures during tests.
  2. Step 2: Identify the benefit in testing context

    By not making real network calls, tests run faster and are more reliable.
  3. Final Answer:

    To avoid making real network calls during tests -> Option A
  4. Quick 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
A. @patch('services.external_api_call.myapp')
B. @patch('external_api_call.myapp.services')
C. @patch('myapp.external_api_call.services')
D. @patch('myapp.services.external_api_call')

Solution

  1. Step 1: Understand patch target format

    The patch decorator requires the full import path to the function or method to mock.
  2. 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'.
  3. Final Answer:

    @patch('myapp.services.external_api_call') -> Option D
  4. Quick 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
A. Error: external_service_call not defined
B. None
C. external_service_call
D. {'status': 'ok'}

Solution

  1. 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.
  2. 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.
  3. Final Answer:

    Error: external_service_call not defined -> Option A
  4. Quick 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
A. external_api_call cannot be patched with patch()
B. The patch context ends before calling external_api_call
C. mock_call.return_value should be set after calling external_api_call
D. Missing import for external_api_call

Solution

  1. Step 1: Check patch context usage

    The patch is applied only inside the with block, but external_api_call is called after it ends.
  2. 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.
  3. Final Answer:

    The patch context ends before calling external_api_call -> Option B
  4. Quick 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
A. Assert response.status_code is 500 to confirm failure handling
B. Remove patch decorator to test real API call
C. Assert mock_call was called once and response.status_code is 200
D. Set mock_call.return_value to None to simulate failure

Solution

  1. Step 1: Understand mocking external payment API

    The patch replaces call_payment with a mock returning an error response.
  2. 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.
  3. Step 3: Check mock call was made

    Asserting mock_call was called confirms the external API was invoked in the view.
  4. Final Answer:

    Assert mock_call was called once and response.status_code is 200 -> Option C
  5. Quick 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