Search code examples
python-3.xhttpresponsehttpconnection

Python: How to mock HTTPSConnection request and response object using json.load


I need to mock below method in my unit test.

def get_app_info(role):
  conn = http.client.HTTPSConnection(url)
  conn.request(
      method="GET",
      url="/v1/profile",
      headers={
          "appName": app["name"],
          "appRole": role
      }
  )

  response = conn.getresponse()
  res_data = json.load(response)
  conn.close()

  return res_data

I tried to patch @patch('http.client.HTTPSConnection'), so request is mocking but its failing at json.load with below error.

raise TypeError(f'the JSON object must be str, bytes or bytearray, ' TypeError: the JSON object must be str, bytes or bytearray, not MagicMock

I tried mocking as below

def mocked_response(*args, **kwargs):
class MockResponse:
    def __init__(self, json_data, status_code):
        self.json_data = json_data
        self.status_code = status_code

    def json(self):
        return self.json_data

return MockResponse(
    {
            "url": "/test/home
        },
        200)

class MyGreatClassTestCase(unittest.TestCase):

@patch('http.client.HTTPSConnection')
@patch('http.client.HTTPResponse')
def test_retrive_token(self, mock_con, mock_resp,  side_effect = mocked_response):

    json_data = common.retrieve_access_token("sometoken")
    print(json_data)

Any inputs are highly appreciated.


Solution

  • I am able to run my unit test cases while mocking HTTPSConnection and HTTPResponse. @patch won't work in this scenario as every time http.client.HTTPSConnection(url) will create new Mock object. So created Mock Request, response and message classes.

    New Mock classes created as

    from MockHTTPResponse import mock_response
    

    def mock_http_connon(self):

    class MockHTTPSConnection(object):
        print(object)
        def request(method, url, body, headers):
            print('request is executed')
    
        def headers(self):
            return "content-type", "accept"
    
        def getresponse():
            return mock_response()
    
        def close():
            print("close MockHTTPSConnection")
    
    return MockHTTPSConnection
    

    Similarly MockResponse and MockMessage.