有没有办法使用 "assert_called_with" 只检查特定的单词?

Is there a way to use "assert_called_with" that only checks specific word?

我正在尝试使用 assert_called_with 断言传递给模拟对象的参数。该函数只有一个参数,但参数非常大。 {"A":{"B": {"C" : {"D": {"key": "keyword", "any": "aaa", "anything": "bbbb"}}}}

我只关心 "key": "keyword" 是否存在,不关心其他东西,有什么办法吗?

假设您的函数有一个参数,即一个嵌套字典,并且在某种程度上包含特定的 key/value 对,您必须使用某些函数手动迭代该字典。

您从 call_args_list 获取模拟函数的所有调用的参数。每个条目都包含一个元组,其中包含位置参数列表和关键字参数,例如call_args_list[0][0][0] 包含第一次调用的第一个位置参数。

假设您测试的函数总是只有一个参数,称为位置参数,您可以这样做:

def dict_contains_key_value(arg, key, value):
    if not isinstance(arg, dict):
        return False
    for k, v in arg.items():
        if k == key and v == value:
            return True
        if dict_contains_key_value(v, key, value):
            return True
    return False


@mock.patch("my_module.sut")
def test_called_arg(mocked):
    caller()  # the function that calls `sut()` several times
    mocked.assert_called()
    assert any(dict_contains_key_value(args[0][0], "key", "keyword")
               for args in mocked.call_args_list)

一些注意事项:

  • 如果您不确定该函数是否始终有一个参数,则必须添加一个检查(例如 args[0]
  • 如果参数也可以作为关键字参数调用,则必须展开检查(args[1]会给你关键字参数的字典)
  • 功能dict_contains_key_value可以根据需要进行优化和扩展,这只是一个简单的例子