我一直在使用python mockito https://code.google.com/p/mockito-python/来测试我的代码。
到目前为止,python mockito似乎只提供了2个匹配器:contains()和any()https://code.google.com/p/mockito-python/wiki/Matchers
我想知道如何编写一些代码以便我可以捕获整个参数。
例如,如果我的代码是
deleteSqlStatement = "DELETE from %s WHERE lower(z_id)=lower('%s') and y_id=%s" \
% (self.SOME_TABLE, zId, yId)
cursor.execute(deleteSqlStatement)
目前,我在验证方面所能做的只是
verify(self.cursor_mock, times=1).execute(contains("DELETE"))
如果我可以捕获作为String执行的整个参数,那将会很棒。
建议?
答案 0 :(得分:1)
我想您可以实现自己的[Matcher]来捕获参数。
class Captor(Matcher):
def matches(self, arg):
self.value = arg
return True
def getValue(self):
return self.value
然后在测试中使用它:
captor = Captor()
verify(self.cursor_mock, times=1).execute(captor)
self.assertEqual("expected query", captor.getValue())
答案 1 :(得分:1)
我还遇到了尝试验证复杂参数的问题。 Mockito当前缺少一种方便的方法,如 unittest.mock 与 call_args 一样,从模拟中获取调用args。
我最后使用(IMHO)第二好的方法是mockito.matchers.arg_that(predicate)
,可以通过自定义方法验证参数。
https://mockito-python.readthedocs.io/en/latest/the-matchers.html#mockito.matchers.arg_that
因此在您的示例中,我们可以将验证步骤重写为:
verify(self.cursor_mock, times=1).execute(arg_that(lambda sql: verify_sql(sql))
然后是可以验证您喜欢的内容的自定义验证方法:
def verify_sql(the_sql):
if the_sql.startswith('SELECT'):
return True
else:
return False
另一个示例(无法获得足够的Mockito示例)
就我而言,我必须验证是否将正确的输入(包括时间戳)发送到模拟的boto3客户端:
verify(boto3_client_mock).put_object_tagging(Bucket="foo-bucket",
Key="foo-prefix",
Tagging=[{'Key':'tag1', 'Value': 'value1'},
{'Key': 'timestamp', 'Value': '1581670796'}])
棘手的是时间戳记,因此常规匹配无法实现。
但是使用arg_that
变得非常简单:
verify(boto3_client_mock).put_object_tagging(Bucket=ANY,
Key=ANY,
Tagging=arg_that(lambda tag_list: verify_tagset(tag_list)))
def verify_tagset(tagset):
for tag in tagset['TagSet']:
# Some verification in here
if yadda:
return True
return False