在单元测试中模拟对象时避免类型警告?

gmo*_*lau 9 python python-unittest python-unittest.mock mypy

假设我有一个函数,它接受一个复杂的对象并用它做一些事情:

def foo(bar: SomeComplexObject):
    ...
Run Code Online (Sandbox Code Playgroud)

在单元测试bar中将被替换为模拟对象,但课程现在会引发类型警告。我应该简单地忽略或抑制这些还是有适当的方法来处理它们(当然不改变原始函数签名)?

更新:我现在已经看到这是mypy 上的一个悬而未决的问题,但它已经处于这种状态两年多了。是否就如何解决这个问题达成了共识?

vbr*_*aun 7

我将把我的 2\xc2\xa2 放入并说你应该对你的测试套件进行类型检查。它的静态代码和静态类型检查将帮助您更快地编写更好的代码。

\n\n

这就留下了如何做的问题。理想情况下,如果您的函数需要SomeComplexObject,那么您还可以传入其实例。要么在你的测试装置中构建一个,要么通过子类化和覆盖你不需要的东西。最好的单元测试是在正确的输入下运行的测试。

\n\n

这仍然是不切实际的情况,或者我们明确想要测试如何处理无效输入的情况。在这种情况下,只需将您的模拟显式转换为 mypy 所需的类型:\n

\n\n
from typing import cast\n\ndef test_foo():\n    mock_bar = cast(SomeComplexObject, MockBar())\n    foo(mock_bar)\n
Run Code Online (Sandbox Code Playgroud)\n

  • 您的回答对我解决类似问题有很大帮助。我想检查我的被测函数内的修补模拟的调用。mypy 抱怨被测函数的返回值没有属性“assert_used_once”。我可以通过恢复您的答案并将“return_value = cast(Mock, return_value)”放在“return_value.inside_call.assert_used_once()”之前来解决我的问题。谢谢你! (2认同)