'Python3 unit tests for API
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.
Solution 1:[1]
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%
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | slideshowp2 |
