samedi 30 juillet 2016

Python 2.7: Error in unit-testing exception using mock library

I'm writing unit test for following method _make_post_request of APIClient class. But I'm having problem in writing unit test for this particular method. This method calls two more methods, out of which one raises an exception. I'm trying to mock both the methods and assert the exception is being raised.

I'm not able to understand how do I mock both methods in correct order, i.e. requests.post and _raise_exception at the same time. Also how can I verify that the exception was indeed raised in the test.

The case I'm testing is when response status_code is not 200 and hence, a APIRequestError exception is raised by _raise_exception method.

import requests

class APIClient:

    def _make_post_request(self, url, data=None, headers=None):
        try:
            resp = requests.post(url, data=data, headers=headers)
            if resp.status_code == 200:
                return resp
            else:
                self._raise_exception(resp)
        except requests.exceptions.ConnectionError:
            print("Connection Error")
        except requests.exceptions.Timeout:
            ......

    @staticmethod
    def _raise_exception(resp):
        status_code = resp.status_code
        error_code = resp.headers['Error-Code']
        error_msg = resp.headers['Error']
        raise APIRequestError(status_code, error_code, error_msg)

Here's what I have tried so far. But this test is failing.

import unittest
import mock

class APITest(unittest.TestCase):

    def setUp(self):
        api = APIClient()

    @mock.patch.object(APIClient, '_raise_exception')
    @mock.patch('APIClient.api.requests.post')
    def test_make_post_request_raise_exception(self, resp, exception):

        resp.return_value = mock.Mock(status_code=500, headers={
                                 'Error-Code': 128, 'Error':'Error'})

        e = APIRequestError(500, 128, 'Error')
        exception.side_effect = e

        req_respone = self.api._make_post_request(url='http://exmaple.com')


        exception_response = self.api._raise_exception(req_response)

        # NOW WHAT TO DO HERE?
        # self.assertRaises(??, ??)
        self.assertRaises(e, exception) # this results in error
        self.assertEqual('', exception_response) # this also results in error

Here's the traceback:

Traceback (most recent call last):
File ".../venv/local/lib/python2.7/site-packages/mock/mock.py", line 1305, in patched
return func(*args, **keywargs)
File ".../api/tests/test_api.py", line 82, in test_make_post_request_raise_exception
req_respone = self.api._make_post_request(url='http://example.com')
File "api/apiclient/api.py", line 52, in _make_post_request
self._raise_exception(resp)
File ".../venv/local/lib/python2.7/site-packages/mock/mock.py", line 1062, in __call__
return _mock_self._mock_call(*args, **kwargs)
File ".../venv/local/lib/python2.7/site-packages/mock/mock.py", line 1118, in _mock_call
raise effect
APIRequestError

Can anyone explain me what could be the possible reason for this error? Which method call is possibly going wrong?

Aucun commentaire:

Enregistrer un commentaire