Mock/create_autospec:验证参数类型



在使用模拟函数的单元测试中,我不仅要验证参数的计数,还要验证这些参数是否符合autospec模拟函数的声明类型。

以下是示例代码:

from unittest.mock import create_autospec

def foo(a: int, b: str):
return str(a) + b
mock_foo = create_autospec(foo)
foo = mock_foo  # would be patched by e.g. @patch or monkeypatch fixture
foo(1, 2)
assert foo.called 

此代码测试是否正确调用了foo。例如,这样的调用将失败:foo(1,2,3)这包括对参数的验证,但不包括对其类型的验证。autospec或其他函数是否有方法验证传递参数的类型?这些信息在方法的签名中是可用的,所以我想我可以使用inspect模块为自己编写这样的验证。但是,有标准的东西吗,内置的还是库?

这可以通过在mock中添加一个比较参数和注释的side_effect来解决:

from unittest.mock import create_autospec
def check_params(method):
def cp(*args, **kwargs):
for arg, typ in zip(args, method.__annotations__.values()):
assert isinstance(arg, typ)
for k, v in kwargs.values():
assert isinstance(v, method.__annotations__[k])
return cp
def foo(a: int, b: str):
return str(a) + b
mock_foo = create_autospec(foo)
mock_foo.side_effect=check_params(foo)
foo = mock_foo  # would be patched by e.g. @patch or monkeypatch fixture
foo(1, 2)
assert foo.called 

这将引发断言错误,因为b应该是str,但却是int

这也可以与类一起使用:从unittest.mock导入create_autospec

def check_params(method):
def cp(*args, **kwargs):
for arg, typ in zip(args, method.__annotations__.values()):
assert isinstance(arg, typ)
for k, v in kwargs.values():
assert isinstance(v, method.__annotations__[k])
return cp
class Foo:
def foo(a: int, b: str):
return str(a) + b
mock_foo = create_autospec(Foo)
mock_foo.foo.side_effect=check_params(Foo.foo)
mock_foo.foo(1, 2)
assert mock_foo.foo.called

最新更新