我正在尝试模拟下面的示例函数。不知怎的,我遇到了错误。 例如, 我有一堂课如下
myclass.py
:
import os, requests
class MyClass:
def __init__(self, login_url):
self.username = os.environ.get('username')
self.password = os.environ.get('password')
self.login_url = login_url
self.auth_credentials = {
'name': self.username,
'password': self.password
}
def get_access_token(self):
token = ""
headers = {
'Authorization': f'Bearer {token}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.post(self.login_url, json=self.auth_credentials, headers=headers, verify=False)
access_token = response.json().get('access_token')
return access_token
现在,我正在进行如下单元测试
unit_test.py
,这实际上抛出了一个错误:
import os
import requests
import unittest
from unittest.mock import Mock, patch, MagicMock
import MyClass
class TestModule(unittest.TestCase):
# @patch('MyClass.get_access_token')
def test_execute(self):
# Test/Mock API:
_obj = MyClass(login_url="https://www.my-website.com/login/")
mock_access_token = "abc123def456ghi789"
with patch('MyClass.get_access_token') as _access:
_access.return_value.status_code = 200
_access.return_value.json.return_value = mock_access_token
response = _obj.get_access_token()
self.assertEqual(response.status_code, 200)
self.assertEqual(response, mock_access_token)
if __name__ == "__main__":
unittest.main()
那么,我在
unit_test.py
中错过了什么?
在这一行中,您将
MyClass.get_access_token
替换为 MagicMock
实例:
with patch('MyClass.get_access_token') as _access:
这意味着每次您调用某些方法时,它将开始返回另一个
MagicMock
。它还会忽略 get_access_token
方法中的所有内容(你用模拟替换了它,还记得吗?)。但是,您的测试代码仍在尝试测试此方法的内部逻辑,例如访问响应的方法。
这里你真正想要模拟的是网络请求,而不是你的方法。您的方法本身没有任何副作用,它调用的库却有。所以你需要模拟库,在这种情况下
requests
。您需要实现适当的模拟,以便当 get_access_token
调用 requests.post
时,它不会实际发出 POST 请求,而是返回具有适当成员的模拟响应(如 json()
)。
由于
requests
有点复杂,您可能会发现这很有帮助:如何模拟请求和响应?