【问题标题】:make Mock.assert_called_with() agnostic to args vs kwargs使 Mock.assert_call_with() 与 args 和 kwargs 无关
【发布时间】:2012-02-05 17:09:28
【问题描述】:

单元测试应该测试功能并尽量不了解实现细节。 Mock.assert_called_with() 是一个方便的函数,但 AFAIK 将 *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)

有没有办法对此进行概括,以便在调用 func 时用作 **kwargs*args 的细节(这实际上是一个实现细节)将被忽略?

【问题讨论】:

  • 我不是 100% 确定我理解你的问题,但是你可以在同一个函数调用中传递 *args 和 **kwargs,或者,因为 args 是元组类型,而 kwargs 是字典,您也许可以编写一个包装函数,将输入标准化为您确定可以工作的输入。
  • 现在是否有任何模拟框架可以做到这一点?我的测试不应该仅仅因为有人决定在某个时候将位置参数更改为关键字参数而失败。但是,这个问题是我见过的唯一一次提到这个问题。 Mock 已经支持规范对象,所以这应该是可能的?

标签: python unit-testing mocking


【解决方案1】:

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

the documentation of the Mock class的最后:

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

>>> 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)

这适用于assert_call_with()、assert_call_once_with()、 assert_has_calls() 和 assert_any_call()。当 Autospeccing 时,它会 也适用于模拟对象的方法调用。

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

【讨论】:

    【解决方案2】:

    提交要模拟的功能请求。

    根本问题是,如果无法访问真正的函数/类 mock,就无法知道关键字参数的顺序,即调用 call(a=1, b=2)call(b=2, a=1) 看起来与 mock 相同,而调用 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)
    

    【讨论】:

    • 也许是时候更新答案了,因为字典会记住 Python 3.6 以来的顺序,我认为函数调用 **kwargs 也可以......
    猜你喜欢
    • 2017-03-26
    • 2013-08-04
    • 2020-09-16
    • 2017-01-28
    • 2021-07-26
    • 2022-09-22
    • 2018-02-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多