Python3 unit tests for API

72 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 best solutions below

0
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%