What if your tests never broke because of slow or missing external services?
Why Testing with external services in PyTest? - Purpose & Use Cases
Start learning this pattern below
Jump into concepts and practice - no test required
Imagine you have a website that talks to a weather service to show the current temperature. Every time you want to check if your site works, you open the site and wait for the real weather service to respond.
This manual way is slow because you wait for the real service every time. Sometimes the service is down or slow, making your testing frustrating. Also, you can't control the weather data, so you can't test special cases easily.
Testing with external services lets you replace the real service with a fake one during tests. This fake service gives quick, predictable answers so your tests run fast and always the same way. You can test all situations without depending on the real service.
import requests def test_weather(): response = requests.get('https://real-weather.com/api') assert response.status_code == 200
import requests def test_weather(monkeypatch): def fake_get(url): class FakeResponse: status_code = 200 return FakeResponse() monkeypatch.setattr(requests, 'get', fake_get) response = requests.get('https://real-weather.com/api') assert response.status_code == 200
It enables fast, reliable, and repeatable tests that work even when the real external service is unavailable or slow.
A developer testing a payment system can fake the bank's response to check how the app handles success, failure, or timeout without calling the real bank every time.
Manual testing with real services is slow and unreliable.
Faking external services makes tests fast and predictable.
This approach helps test all scenarios safely and repeatedly.
Practice
Solution
Step 1: Understand the role of mocking in tests
Mocking replaces real external calls with fake ones to avoid delays and failures.Step 2: Identify the benefit of mocking external services
Mocking makes tests faster and more reliable by not depending on real services.Final Answer:
To avoid calling the real external service and make tests faster -> Option AQuick Check:
Mocking speeds up tests by faking external calls [OK]
- Thinking mocking increases real API calls
- Believing tests should depend on internet speed
- Confusing testing external service with testing your code
get_data from module external_api using pytest's patch decorator?Solution
Step 1: Recall correct patch syntax
The patch decorator requires the full import path as a string: 'module.function'.Step 2: Match the correct option
@patch('external_api.get_data') uses 'external_api.get_data' which is the correct format and case-sensitive.Final Answer:
@patch('external_api.get_data') -> Option AQuick Check:
patch('module.function') syntax is correct [OK]
- Swapping module and function order
- Using wrong separators like '->'
- Incorrect function name casing
from unittest.mock import patch
import requests
def fetch_status():
response = requests.get('https://api.example.com/data')
return response.status_code
@patch('requests.get')
def test_fetch_status(mock_get):
mock_get.return_value.status_code = 200
assert fetch_status() == 200
print('Test passed')Solution
Step 1: Understand mocking effect on requests.get
The patch replaces requests.get with a mock that returns an object with status_code 200.Step 2: Check assertion and print statement
fetch_status() returns 200, matching the assertion, so 'Test passed' is printed.Final Answer:
Test passed -> Option CQuick Check:
Mocked return_value.status_code = 200 makes test pass [OK]
- Forgetting to set return_value.status_code
- Expecting real HTTP call instead of mock
- Missing print output due to assertion failure
from unittest.mock import patch
import myservice
@patch('myservice.call_api')
def test_api(mock_call):
mock_call.return_value = {'status': 'ok'}
result = myservice.call_api()
assert result.status == 'ok'Solution
Step 1: Analyze the mocked return value type
The mock returns a dictionary {'status': 'ok'}, so result is a dict.Step 2: Check the assertion syntax
Accessing dict keys requires bracket notation, not dot notation; result.status causes AttributeError.Final Answer:
The assertion should use result['status'] instead of result.status -> Option BQuick Check:
Dict keys need brackets, not dot notation [OK]
- Using dot notation on dicts
- Forgetting parentheses in patch decorator (not here)
- Expecting return_value must be string always
process_data() that calls an external API fetch_data(). The API sometimes returns null. How should you mock fetch_data in pytest to test process_data handles null correctly?Solution
Step 1: Understand the need to test null handling
Since fetch_data can return null, tests must simulate this to check process_data behavior.Step 2: Use patch to mock fetch_data returning null
Mocking fetch_data to return null allows controlled testing of process_data's handling of that case.Final Answer:
Use patch to make fetch_data return null and assert process_data handles it -> Option DQuick Check:
Mock null return to test edge case handling [OK]
- Calling real external API in tests
- Mocking only success cases, ignoring null
- Ignoring exceptions instead of testing them
