python mockito参数捕获者

时间:2014-09-10 13:42:03

标签: python testing mockito

我一直在使用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执行的整个参数,那将会很棒。

建议?

2 个答案:

答案 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