Strobe_
Strobe_

Reputation: 515

Python Requests - Mock status code and response

So I'm writing some unit tests for a Python project and I want to mock a response to an external API.

My code looks like this:

r = my_api_client.get(myurl)

try:
    if r.status_code == 200:
        my_response = r.json()
    elif r.status_code != 200:
        print "bad status code"
except Exception as e:
    raise

for x in my_response:
    ...

My question is how do I mock my_api_clientto return a proper status code and json object?

I've been trying things like my_api_client = mock.Mock(return_value={'status_code':200, 'json_obj': {'blah':'blah'}})

Thanks for any help

Upvotes: 10

Views: 22455

Answers (1)

Guido
Guido

Reputation: 308

You can compose a complex mock for the response, like this:

ok_response_mock = mock.MagicMock()
type(ok_response_mock).status_code = mock.PropertyMock(return_value=200)
ok_response_mock.json.return_value = "{'blah':'blah'}"

This creates a MagicMock (that doesn't complain when asked for non-speficied methods), adds the status_code property to it, which returns 200. And configures the JSON string response to the .json() method.

So, if my_api_client is a parameter in your test method:

my_api_client_mock = mock.MagicMock()
my_api_client_mock.get.return_value = ok_response_mock
YourModule.YourMethod(my_api_client_mock)

This creates the mock parameter, connects it to the previously created mock response and calls the test method. If, instead, my_api_client is an imported module:

@mock.patch('MyModuleUnderTest.my_api_client')
def test_MyMethodUnderTest__response_ok__stuff_happens(self, api_client_mock):
   # code to create ok_response_mock
   api_client_mock.get.return_value = ok_response_mock

This will patch the imported module with a mock, automatically created for you and placed as an argument to your test method. Just tell that mock to return the mocked response.

Upvotes: 13

Related Questions