Python中如何通过其他函数更新已创建的Mock对象?
unittest.mock.patch via another function? I've created a Mock object for
requests.getusing the following code:with patch('requests.get') as request: self.request = request self.request.session = MockSession() self.request.cookies = {}How can I update this Mock object using another function?
Great question! Updating a Mock object created with unittest.mock.patch is straightforward—here are a few common approaches depending on your setup:
1. Pass the Mock directly to your update function
The simplest method is to hand your existing self.request Mock instance to the function that needs to modify it. The function can tweak attributes, add new ones, or configure return values just like you did when initializing the Mock.
Example code:
def update_request_mock(mock_obj): # Update existing cookie attributes mock_obj.cookies = {"session_id": "abc123", "user_token": "xyz789"} # Add a new header attribute mock_obj.headers = {"Authorization": "Bearer my-token"} # Configure the mock's return value for requests.get calls mock_obj.return_value.status_code = 200 mock_obj.return_value.json.return_value = {"status": "success", "data": "updated"} # Inside your test context with patch('requests.get') as request: self.request = request self.request.session = MockSession() self.request.cookies = {} # Call the update function to modify the mock update_request_mock(self.request) # Test with the updated mock response = requests.get("https://api.example.com/data") assert response.status_code == 200 assert response.json()["data"] == "updated"
2. Access the Mock via the patched target (if in scope)
If your update function runs within the same patch context, you can directly reference requests.get—since the patch replaces the real function with your Mock, modifying requests.get will update your original Mock instance.
Example:
def tweak_request_mock(): # Inside the patch context, requests.get is our Mock requests.get.cookies.update({"new_cookie": "fresh-value"}) requests.get.return_value.text = "Updated response content" # Override the session attribute if needed requests.get.session = MockSession(active=True) # Inside your test with patch('requests.get') as request: self.request = request self.request.session = MockSession() self.request.cookies = {} tweak_request_mock() # Verify changes took effect assert requests.get.cookies["new_cookie"] == "fresh-value" assert requests.get.return_value.text == "Updated response content"
3. Use a class helper method (for test classes)
If you're writing tests in a unittest.TestCase subclass, create a helper method within the class that modifies the self.request Mock directly. This keeps your test code organized.
Example:
import unittest from unittest.mock import patch, Mock class MyAPITests(unittest.TestCase): def setUp(self): # Start the patch and store the Mock in self.request self.patch = patch('requests.get') self.request = self.patch.start() self.request.session = Mock() # Using a basic Mock for example self.request.cookies = {} def tearDown(self): # Stop the patch after tests run self.patch.stop() def _update_request_mock(self): # Modify the class-level Mock instance self.request.cookies.update({"user_id": "456"}) self.request.session.user = "test-user-123" self.request.return_value.status_code = 401 # Simulate unauthorized def test_unauthorized_access(self): self._update_request_mock() # Run your code under test that calls requests.get result = my_protected_api_function() # Assert based on the updated Mock self.assertEqual(result, "Unauthorized") self.assertEqual(self.request.return_value.status_code, 401)
Key Reminders
- Always make sure your update function runs inside the patch context (before the
withblock exits orpatch.stop()is called). Once the patch ends,requests.getreverts to the real function, and your Mock changes won't apply. - You can modify any aspect of the Mock—attributes, return values, side effects, or child Mocks (like
sessionorreturn_value)—just like you did during initialization.
内容的提问来源于stack exchange,提问作者systemdebt

