Python Mockito 参数捕获器

3 投票
2 回答
3700 浏览
提问于 2025-04-20 21:19

我一直在用 python mockito https://code.google.com/p/mockito-python/ 来测试我的代码。

到目前为止,python mockito 似乎只提供了两个匹配器: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"))

如果我能把传给 execute 的整个参数捕获为一个字符串,那就太好了。

有什么建议吗?

2 个回答

1

我也遇到了验证复杂参数的问题。Mockito 目前缺少一种方便的方法来获取模拟对象的调用参数,就像 unittest.mock 使用 call_args 那样。

最后,我使用了(在我看来)第二好的方法,就是 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
4

我想你可以自己实现一个 [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())

撰写回答