我有一个用于从另一个非常简单的服务获取信息的对象。由于对象很简单并且初始化方法可以很容易地修补,我想我会尝试编写我的代码以实现超级可重用和可扩展。但是,唉,我不知道如何使它工作。下面的代码是相当不错的 sudo 代码,并且非常简化,但它应该明白这一点。
class SimpleClient:
def __init__(self):
pass
def read(self, key, path='some/path'):
return value_from_get_on_another_service
然后我有一个请求处理程序对象,它通过 get_client() 初始化客户端(见下文)
def get_client():
return SimpleClient()
然后请求处理程序上的一个方法使用不同参数的 client.read() 方法几次(第二个取决于第一个)。
对于我的测试,我认为我可以“修补”get_client 方法以返回我自己的简单对象,然后可以“定期”使用该对象并消除对第三方服务的依赖,并实际使用从方法执行中检索到的值。我很失望地发现它不是那么容易和干净。测试模式如下所示。
class MockClient:
def __init__(self, addr='someAddr', token='someToken'):
pass
def read(self, value, prefix):
data = {}
if prefix == 'path/1':
data = self.p1_lookup(value)
elif prefix == 'path/2':
data = self.p2_lookup(value)
return self.response_wrapper(data)
def p2_lookup(self, key):
data = {
'key1': {
'sub_key': {"55B3FE7D-9F43-4DD4-9090-9D89330C918A": "Dev2",
"7A1C2F4B-E91C-4659-A33E-1B18B0BEE2B3": "Dev"}
}
}
return data.get(key, {})
@mock.patch('a.module.get_client')
def test_authorize_valid_request_no_body(mock_get_client):
request = RequestMock()
request.body = None
handler = RequestHandler(Application(), request=request, logging_level='INFO')
mock_get_client.return_value = MockClient()
handler.authorize_request()
assert handler.verified_headers is None
assert handler.verified_body is None
assert handler.user_authenticated is False
我已经看到在哪里可以模拟实际 client.read() 的响应以返回带有列表的多个值。但这似乎我会做大量的复制和粘贴,并且必须为每个小测试一遍又一遍地做同样的事情。如果这很简单,请原谅我,遗憾的是我只是在学习测试的艺术。有没有办法完成我想做的事情?也许我缺少一些超级简单的东西。或者,也许我只是无缘无故地走错了路。帮助?!