【问题标题】:How do I mock and unit test the following code?如何模拟和单元测试以下代码?
【发布时间】:2015-04-12 00:30:39
【问题描述】:
import module
from x import X

class A:
   def method(): 
       return module.something(arg=X())

我创建了以下单元测试:

with patch('filename.module.something') as something_mock:
   with patch('filename.X'): as x_mock:
       a.method()
something_mock.assert_called_once_with(arg=x_mock.return_value)
x_mock.assert_called_once_with()

有人提到没有解释就没有必要嘲笑filenme.X。有没有其他方法可以在不模拟filename.X 的情况下验证对something 的调用?我将如何更改以下断言来验证调用?

something_mock.assert_called_once_with(arg=_____) 

【问题讨论】:

  • 如果你的代码真的像给出的例子,那么单元测试的意义何在?在这个代码级别没有发生任何事情——根本没有逻辑、算法或数据复杂性。 FWIW,随着时间的流逝,我发现自己嘲笑的次数越来越少,编写的单元测试越来越少,并且编写更多(和更有趣)的集成或端到端测试来运行系统的更大组件。
  • @FMc 为了清楚起见,代码被简化
  • 这个答案可能会有所帮助:stackoverflow.com/questions/8658043/how-to-mock-an-import
  • @FMc ...有趣...我做了完全相反的路径:)。恕我直言,如果没有良好且广泛的单元测试,集成测试的用处就会降低:当集成测试失败时,单元测试会为您提供一个非常坚实的基础,即您可以信任什么以及您的代码/设计中可能存在一些漏洞。

标签: python unit-testing mocking


【解决方案1】:

如果 create X 不是问题(即数据库连接或网络访问),您可以在不模拟的情况下进行测试。

您有以下选择:

  1. 如果您不想检查您的方法如何调用something_mock,请使用mockcalled 属性
  2. 如果您想检查 something_mock 是否已被 arg 关键字 arg 调用,但您对值是什么不感兴趣,请使用 mock.ANY
  3. 使用call_args提取something_mock调用参数并通过calls as tuple提取arg

第一个是

assert something_mock.called

第二个是

something_mock.assert_called_once_with(arg=mock.ANY)

最后是第三个

args, kwargs = something_mock.call_args
assert isinstance(kwarg['arg'], x.X)

最后一个选项与模拟 X 完全相同,但我写它只是为了显示所有可能性。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多