I would like to write a unit test case for HTTPError exception part based on the error response content I get. But I have now idea how I can mock the response so that the unit test can reach doSomething1() instead of doSomething2().
foo.py
def get_result_from_API():
#Try to call API here...
def getSomething():
try:
result = get_result_from_API()
except HTTPError as error:
error_json = error.response.json()
if error_json.get("error").get("code") == "00001":
doSomething1()
else:
doSomething2()
raise error
Unit Test
@patch('foo.doSomething2')
@patch('foo.doSomething1')
@patch('foo.get_result_from_API')
def testGetSomething(get_result_from_API,doSomething1,doSomething2):
mock_response = Mock()
mock_response.return_value = {
"error":{
"code": "00001",
"message": "error message for foo reason"
}
}
get_result_from_API.side_effect = HTTPError(response=mock_response)
with self.assertRaises(HTTPError):
foo.getSomething()
doSomething1.assert_called_once()
The current result is that doSomething1() is not called where as doSomething2() is called.
Since the getSomething
function calls:
error_json = error.response.json()
the solution is to mock the call to .json()
mock_response.json.return_value = {
"error":{
"code": "00001",
"message": "error message for foo reason"
}
}
As it was originally written, getSomething
would have had to have called response()
directly.
error_json = error.response()
Here is a more generic example:
>>> from unittest.mock import Mock
>>> mock_response = Mock()
>>> mock_response.return_value = {"hello": "world"}
>>> mock_response() # call response() directly
{'hello': 'world'}
>>> mock_response.json() # no return_value is assigned to the json() call
<Mock name='mock.json()' id='4407756744'>
>>> mock_response.json.return_value = {"hello": "universe"} # assign a json() return_value
>>> mock_response.json()
{'hello': 'universe'}
If you want, you can even do this while instantiating Mock:
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.