Create a functioning Response object

Question:

For testing purposes I’m trying to create a Response() object in python but it proves harder then it sounds.

i tried this:

from requests.models import Response

the_response = Response()
the_response.code = "expired"
the_response.error_type = "expired"
the_response.status_code = 400

but when I attempted the_response.json() i got an error because the function tries to get len(self.content) and a.content is null.
So I set a._content = "{}" but then I get an encoding error, so I have to change a.encoding, but then it fails to decode the content….
this goes on and on. Is there a simple way to create a Response object that’s functional and has an arbitrary status_code and content?

Asked By: Dotan

||

Answers:

That because the _content attribute on the Response objects (on python3) has to be bytes and not unicodes.

Here is how to do it:

from requests.models import Response

the_response = Response()
the_response.code = "expired"
the_response.error_type = "expired"
the_response.status_code = 400
the_response._content = b'{ "key" : "a" }'

print(the_response.json())
Answered By: Or Duan

Just use the responses library to do it for you:

import responses

@responses.activate
def test_my_api():
    responses.add(responses.GET, 'http://whatever.org',
                  json={}, status=400)

    ...

This has the advantage that it intercepts a real request, rather than having to inject a response somewhere.

Answered By: jonrsharpe

Create a mock object, rather than trying to build a real one:

from unittest.mock import Mock

from requests.models import Response

the_response = Mock(spec=Response)

the_response.json.return_value = {}
the_response.status_code = 400

Providing a spec ensures that the mock will complain if you try to access methods and attributes a real Response doesn’t have.

Answered By: jonrsharpe

Another approach by using the requests_mock library, here with the provided fixture:

import requests


def test_response(requests_mock):
    requests_mock.register_uri('POST', 'http://test.com/', text='data', headers={
        'X-Something': '1',
    })
    response = requests.request('POST', 'http://test.com/', data='helloworld')

    ...
Answered By: AngryUbuntuNerd
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.