我正在python中测试一个自定义API来发出http请求,但我不希望每次运行单元测试时都向真实的外部系统发出请求。我正在使用带有side_effect函数的python模拟库来动态伪造API响应。如何让side_effect方法像类方法一样?
import requests
class MyApiClass():
def make_request(self, params):
return requests.get('http://someurl.com', params=params)
def create_an_object(self, params):
return self.make_request(params)
import unittest, mock
def side_effect_func(self, params):
if params['name'] == 'Specific Name':
return {'text': 'Specific Action'}
else:
return {'text': 'General Action'}
class MyApiTest(unittest.TestCase):
def setUp(self):
super(MyApiTest, self).setUp()
mocked_method = mock.Mock(side_effect=side_effect_func)
MyApiClass.make_request = mocked_method
def test_create_object(self):
api = MyApiClass()
params = {'name': 'Specific Name'}
r = api.create_an_object(params) # Complains that two arguments are needed!
self.assertEqual(r['text'], 'Specific Action')
我收到此错误
TypeError: side_effect_func() takes exactly 2 arguments (1 given)
但我希望side_effect_func
传递api
作为第一个参数。感谢任何帮助!
答案 0 :(得分:4)
最简单的方法可能是让你的mock方法接受一个参数,然后在mock方法本身内静态引用MyApiClass
。否则,您可以尝试模拟类对象本身(基本上是创建一个模拟元类),或者使用一个使用partial
的工厂来动态构建一个模拟类方法。但是如果单个参数/静态参考方法对你有用,那对我来说似乎是最好的。
此外,从模拟文档中,有mocking an unbound method using patch,看起来它可能更符合您的需求。