如何使用Mock测试服务请求响应,解决get_req无返回的断言失败问题
问题原因
get_req方法没有返回response对象,调用obj.get_req()拿到的是None,自然不存在json()方法,触发属性错误。
解决方案
提供两种可选方案,根据是否允许修改业务代码选择:
方案1:修改业务代码(推荐,适配常规调用逻辑)
给get_req方法补充返回response的逻辑,修改后的业务代码如下:
import requests class Attt(): def get_req(self): pload = {'username': 'Olivia', 'password': '123'} r = requests.post('https://httpbin.org/post', data=pload) print(r.text) print(r.content) # 新增返回响应对象 return r obj=Attt() obj.get_req()
同时测试代码将断言放在with块内避免mock失效,调整后如下:
import unittest from unittest.mock import patch from mock_tutorial.attt import Attt class TestMockService(unittest.TestCase): def test_mock(self): fake_json = [{'test': "mock"}] with patch('mock_tutorial.attt.requests.post') as mock_post: # 统一配置mock返回值的所有用到的属性 mock_resp = mock_post.return_value mock_resp.status_code = 200 mock_resp.json.return_value = fake_json # 适配业务代码里的text、content调用,避免打印mock对象信息 mock_resp.text = "fake text" mock_resp.content = b"fake content" obj = Attt() response = obj.get_req() print('response json', response.json()) # 断言放在with块内,此时mock仍生效 self.assertEqual(response.status_code, 200) self.assertEqual(response.json(), fake_json) # 额外可校验post请求参数是否符合预期 mock_post.assert_called_once_with('https://httpbin.org/post', data={'username': 'Olivia', 'password': '123'}) if __name__ == "__main__": unittest.main()
方案2:不修改业务代码,直接校验mock对象
如果不能改动原业务代码,不需要通过返回值断言,直接校验mock的post方法的调用情况和返回值配置即可:
import unittest from unittest.mock import patch from mock_tutorial.attt import Attt class TestMockService(unittest.TestCase): def test_mock(self): fake_json = [{'test': "mock"}] with patch('mock_tutorial.attt.requests.post') as mock_post: mock_resp = mock_post.return_value mock_resp.status_code = 200 mock_resp.json.return_value = fake_json mock_resp.text = "fake text" mock_resp.content = b"fake content" obj = Attt() # 不需要接收返回值 obj.get_req() # 直接断言mock返回值的属性符合预期 self.assertEqual(mock_resp.status_code, 200) self.assertEqual(mock_resp.json(), fake_json) # 校验请求参数正确 mock_post.assert_called_once_with('https://httpbin.org/post', data={'username': 'Olivia', 'password': '123'}) if __name__ == "__main__": unittest.main()
内容的提问来源于stack exchange,提问作者Ian Kurtis
相关产品推荐
相关产品推荐

