unittest.mock.patch in PyTest - Build an Automation Script
import pytest from unittest.mock import patch, Mock # Assume these are in your module named 'my_module' import my_module def test_process_data_with_mocked_get(): mock_response = Mock() mock_response.json.return_value = {'key': 'value'} with patch('my_module.requests.get', return_value=mock_response) as mock_get: result = my_module.process_data() # Assert the processed result is as expected assert result == 'Processed value', f"Expected 'Processed value' but got {result}" # Assert requests.get was called once with the expected URL mock_get.assert_called_once_with('https://api.example.com/data')
This test uses unittest.mock.patch as a context manager to replace requests.get with a mock object during the test. We create a mock response object whose json() method returns a fixed dictionary. This simulates the API response without making a real HTTP call.
We then call process_data(), which internally calls get_data() that uses requests.get. Because of the patch, it receives the mocked response.
We assert that the processed result matches the expected output based on the mocked data. We also verify that requests.get was called exactly once with the correct URL, ensuring our code calls the API as expected.
This approach keeps tests fast, reliable, and independent from external services.
Now add data-driven testing with 3 different mocked API responses and verify process_data handles each correctly
Practice
unittest.mock.patch in pytest?Solution
Step 1: Understand the role of patch
unittest.mock.patchis used to replace parts of your code temporarily during tests, so you can control how those parts behave without running the real code.Step 2: Compare with other options
The other options describe generating test data, speeding up tests by skipping them, or checking syntax, none of whichpatchperforms.Final Answer:
To replace parts of the code temporarily during tests to control behavior -> Option DQuick Check:
Patch replaces code parts temporarily [OK]
- Thinking patch speeds up tests by skipping them
- Confusing patch with test data generation
- Believing patch checks code syntax
requests.get using a decorator in pytest?Solution
Step 1: Understand patch decorator syntax
The patch decorator requires the target as a string with the full path, like 'module.function'. So, '@patch('requests.get')' is correct.Step 2: Identify incorrect syntax
@patch(requests.get) misses quotes around the target, @patch('requests.get()') adds incorrect parentheses, and @patch('requests->get') uses an invalid arrow symbol.Final Answer:
@patch('requests.get') -> Option CQuick Check:
Patch target must be a string path [OK]
- Omitting quotes around the target string
- Adding parentheses after the function name
- Using invalid symbols like arrows in the target
import requests
from unittest.mock import patch
def fetch_data():
return requests.get('http://example.com').status_code
@patch('requests.get')
def test_fetch(mock_get):
mock_get.return_value.status_code = 404
print(fetch_data())
if __name__ == '__main__':
test_fetch()Solution
Step 1: Understand patch effect on requests.get
The decorator replacesrequests.getwith a mock object. The mock'sreturn_value.status_codeis set to 404.Step 2: Trace fetch_data call
Whenfetch_data()callsrequests.get, it gets the mock, whosestatus_codeis 404, so it returns 404.Final Answer:
404 -> Option AQuick Check:
Mock return_value.status_code = 404 means fetch_data() returns 404 [OK]
- Expecting real HTTP status 200 instead of mocked 404
- Confusing mock object with None
- Thinking patch causes an error here
from unittest.mock import patch
def test_api_call():
with patch('api.requests.get') as mock_get:
mock_get.status_code = 200
response = api_call()
assert response == 'success'Solution
Step 1: Understand mock object structure
When patching a function, the mock object replaces the function. The function call returnsmock_get.return_value. So, attributes likestatus_codemust be set onmock_get.return_value.Step 2: Identify the error in code
The code setsmock_get.status_code = 200which is incorrect; it should bemock_get.return_value.status_code = 200.Final Answer:
mock_get.status_code should be set on mock_get.return_value, not mock_get -> Option BQuick Check:
Set attributes on return_value, not mock function [OK]
- Setting attributes directly on the mock function
- Forgetting quotes around patch target
- Thinking patch must be decorator only
- Miswriting assert syntax
process_data() that calls fetch_from_api() internally. You want to patch fetch_from_api only during the test to return a fixed value. Which is the best way to do this using unittest.mock.patch?Solution
Step 1: Understand patch scope and usage
Using@patch('module.fetch_from_api')decorator temporarily replacesfetch_from_apionly during the test, allowing control over its return value.Step 2: Evaluate other options
Replacefetch_from_apiglobally in the module before running tests changes global code, which is unsafe. Modifyfetch_from_apicode to return fixed value during tests modifies production code, which is bad practice. Callfetch_from_apidirectly in the test without patching does not isolate the test.Final Answer:
Use @patch('module.fetch_from_api') decorator on the test function and set mock_fetch.return_value -> Option AQuick Check:
Patch with decorator for safe, temporary replacement [OK]
- Changing global code instead of patching
- Modifying production code for tests
- Not patching and calling real function
Ready to prove it?
Pass the test and this pattern moves unknown
