覆盖模拟对象的“is”运算符

时间:2021-01-27 15:13:59

标签: python mocking overriding python-unittest python-unittest.mock

简化代码:我有一个函数,它需要一个数字或 None,如果它是 True,则返回 None,如果它是一个数字,则返回 False,例如:

def function(var):
    return var is None

我想传递一个模拟对象并像这样使用 is 运算符对其进行测试:

from unittest.mock import Mock

mock = Mock(return_value=None)
assert function()

尽管我将值模拟为 None,但这会失败。根据 documentation,有许多受支持的魔法方法,但没有一个让我实现这种情况的行为。

更改为 assert mock == None 可以让我使用 __eq__ 运算符,但我不想触及代码(并且显然使用 is== 根据this answer)

3 个答案:

答案 0 :(得分:0)

也许使用 isinstance() 代替 is 对您有用。将您的模拟对象类声明为 class MockInt(int): 将使 isinstance() 将变量识别为 int:

class MockInt(int):
      def __init__(self,value): self.value = value

i = MockInt(23)

print( isinstance(i,int) ) # True 

答案 1 :(得分:0)

TL;DR

当有 return_value 时不要忘记括号

from unittest.mock import Mock

mock = Mock(return_value=None)
assert function(mock())

更多信息

如果您想传递一个包含 None 的变量来测试 function,则无需使用 Mock。您可以编写以下代码:

mock = None
assert function(mock)

Mock 的最佳用法是当您想要模拟具有更复杂结构的方法或对象时。因此,当您编写 mock = Mock(return_value=None) 时,您必须调用 mock 以返回 return_value

答案 2 :(得分:0)

正如许多人指出的那样,is 是“不可覆盖的”,因为它是对 id 的快速相等检查。这就是与 __eq__ 相比存在性能差异的原因。

the docsthis answer 的评论中详细介绍了这一点。

相关问题