使Mock.assert_called_with()与args vs kwargs无关

Jon*_*han 10 python unit-testing mocking

单元测试应该测试功能并尝试与实现细节无关. Mock.assert_called_with()是一个方便的功能,但据我所知它比较*args*args**kwargs**kwargs.因此:

# class to be mocked during test
class SomeClass():
    def func(self,a,b,c=5):
        # ...

# code under test
somaclass_instance.func(1,b=2,c=3)

# test code that works
someclass_mock.func.assert_called_with(1,b=2,c=3)

# test code that won't work
someclass_mock.func.assert_called_with(1,2,c=3)
someclass_mock.func.assert_called_with(a=1,b=2,c=3)
Run Code Online (Sandbox Code Playgroud)

有没有一种方法来概括这一点,以便在调用*args中使用的具体内容(实际上是一个实现细节)将被忽略?**kwargsfunc

tal*_*nat 9

从 Python 3.4 开始,就像您想要的那样,当使用规范创建可调用 Mock 时,对特定调用签名的断言会自动规范化,并在使用自动规范时对对象方法进行规范化。

Mock 类的文档的最后

使用规范(或 spec_set)创建的可调用模拟将在匹配对模拟的调用时内省规范对象的签名。因此,它可以匹配实际调用的参数,无论它们是按位置传递还是按名称传递:

>>> def f(a, b, c): pass
...
>>> mock = Mock(spec=f)
>>> mock(1, 2, c=3)
<Mock name='mock()' id='140161580456576'>
>>> mock.assert_called_with(1, 2, 3)
>>> mock.assert_called_with(a=1, b=2, c=3)
Run Code Online (Sandbox Code Playgroud)

这适用于 assert_Called_with()、assert_Called_once_with()、assert_has_calls() 和 assert_any_call()。当 Autospeccing 时,它也将适用于模拟对象上的方法调用。

在 3.4 版更改: 添加了对指定和自动指定模拟对象的签名自省。


Dim*_*nek 5

提交要模拟的功能请求.

根本的问题是,没有进入真正的函数/类模拟无法知道的关键字参数的顺序的方法,即调用call(a=1, b=2)call(b=2, a=1)看起来与嘲笑,而调用call(1, 2)call(2, 1)没有.

如果你想概括mock,你需要传递一个调用原型或一个函数来代替原型,例如:

amock.afunc.assert_called_with(1, 2, c=3, __prototype__=lambda a=None, b=None, c=None: None)
Run Code Online (Sandbox Code Playgroud)