As part of my unittests, I am testing some responses using the fantastic Requests library. Something cool you can do with this library is test a response for a 200
OK status code by simply calling:
r = requests.get("http://example.com")
if r:
# success code, do something...
else:
# error code, handle the error.
The way this works behind the scenes is Requests updates the __bool__()
protocol method of the response returned according to the type of status code.
What I'd like to do is to be able to mock the response object of requests.get()
well enough so that I can not only patch the methods/attributes I'm interested in checking (status_code
, json()
) but also to be able to return False
whenever I choose to.
The following isn't working for me, as once I call r
from the sample code above, it returns the Mock object <Mock id='2998569132'>
which evaluates to True
.
with mock.patch.object(requests, 'get', return_value=mock.MagicMock(
# False, # didn't work
# __bool__=mock.Mock(return_value=False), # throws AttributeError, might be Python2.7 problem
# ok=False, # works if I call if r.ok: instead, but it's not what I want
status_code=401,
json=mock.Mock(
return_value={
u'error': {
u'code': 401,
u'message':
u'Request had invalid authentication credentials.',
u'status': u'UNAUTHENTICATED'
}
}
)
)) as mock_account_get_failure:
# mock_account_get_failure.return_value = False # overwrites what I just mocked with json() and status_code
I thought the answer might lie in Magic Mocking the protocol method's return value, but read here that __bool__
is only supported for Python 3.0.
In python2.7, you should mock __nonzero__
instead of __bool__
.
m = mock.MagicMock(__nonzero__=mock.Mock(return_value=False), status_code=400)
m.status_code # > 400
bool(m) # > False
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With