Python3 unit tests for API

28 views Asked by At

I could use some much needed guidance on unit tests for python3

All my files are in the same directory. No Sub folders.

Params is a class that gets initialized in the script. FILE 1 works fine connecting to the API.

#FILE 1 AssetsSensu.py

import requests
import json
from Params import params


class Assets():
    def GetAssets():
        response = requests.request(
            "GET", params.url+"assets", headers=params.headers, verify=params.verify)
        return response

#FILE 2 AssetsSensu_tests.py

from Params import params
from AssetsSensu import Assets
from unittest import TestCase,  mock


class TestAPI(TestCase):
    @mock.patch('AssetsSensu.Assets.GetAssets', return_val=200)
    def test_GetAssets(self, getassets):
        self.result = Assets.GetAssets().status_code
        self.assertEquals(self.result, 200)

I am getting this result, running Assets.GetAssets().status_code returns 200 in either file.

AssertionError: <MagicMock name='GetAssets().status_code' id='140685448294016'> != 200

Inside File 2 "getassets" is not highlighted which means to me it's not being used. If I remove it I get the following error

TypeError: test_GetAssets() takes 1 positional argument but 2 were given

command being used is python3 -m unittest AssetsSensu_tests.py

Help would be greatly appreciated.

1

There are 1 answers

0
Lin Du On

You are testing the GetAssets method so you should NOT mock it. Instead, you should mock requests.request method and its return value. We use requests.Response() class to create a mocked response.

E.g. (Python 3.9.6, requests==2.26.0)

AssetsSensu.py:

import requests
from Params import params


class Assets():
    def GetAssets():
        response = requests.request(
            "GET", params.url+"assets", headers=params.headers, verify=params.verify)
        return response

Params.py:

from collections import namedtuple

requestOptions = namedtuple("RequestOptions", ["url", "headers", "verify"])
params = requestOptions('http://localhost:8080/api/', {}, False)

AssetsSensu_tests.py:

import unittest
from AssetsSensu import Assets
from unittest import TestCase,  mock
import requests


class TestAPI(TestCase):
    @mock.patch('AssetsSensu.requests')
    def test_GetAssets(self, mock_requests):
        resp = requests.Response()
        resp.status_code = 200
        mock_requests.request.return_value = resp
        result = Assets.GetAssets()
        self.assertEqual(result.status_code, 200)
        mock_requests.request.assert_called_once_with("GET", "http://localhost:8080/api/assets", headers={}, verify=False)



if __name__ == '__main__':
    unittest.main()

Test result:

coverage run /Users/dulin/workspace/github.com/mrdulin/python-codelab/src/stackoverflow/71782055/AssetsSensu_tests.py && coverage report -m
.
----------------------------------------------------------------------
Ran 1 test in 0.001s

OK
Name                                              Stmts   Miss  Cover   Missing
-------------------------------------------------------------------------------
src/stackoverflow/71782055/AssetsSensu.py             6      0   100%
src/stackoverflow/71782055/AssetsSensu_tests.py      15      0   100%
src/stackoverflow/71782055/Params.py                  3      0   100%
-------------------------------------------------------------------------------
TOTAL                                                24      0   100%