【问题标题】:Why would mock be adding __nonzero__ method calls?为什么 mock 会添加 __nonzero__ 方法调用?
【发布时间】:2012-12-26 21:03:28
【问题描述】:

我有一段代码调用集合中每个项目的一系列方法,每个方法返回一个布尔值,指示成功 = True/failure = False。

def monkey(some_collection, arg1, arg2):
    for item in some_collection:
        if not item.foo(arg1, arg2):
            continue
        if not item.bar(arg1, arg2):
            continue
        if not item.baz(arg1, arg2):
            continue

还有,这是我的单元测试示例:

import mock
def TestFoo(unittest.TestCase):
    def test_monkey(self):
        item = MagicMock()
        some_collection = [item]
        collection_calls = []
        foo_call = mock.call().foo(some_collection, 1, 2)
        bar_call = mock.call().bar(some_collection, 1, 2)
        baz_call = mock.call().baz(some_collection, 1, 2)
        collection_calls = [foo_call, bar_call, baz_call]                   
        my_module.monkey(some_collection, 1, 2)
        item.assert_has_calls(collection_calls) # requires the correct call order/sequence

实际通话

  1. call().foo(<MagicMock id='12345'>, 1, 2)
  2. call().foo.__nonzero__()

...

注意:此单元测试失败,因为它看到了 __nonzero__() 方法调用。

问题

为什么要添加非零方法调用?

澄清

我正在使用mock,它从 python 3.3 开始包含在 stdlib 中。

【问题讨论】:

    标签: python unit-testing mocking


    【解决方案1】:

    简答:

    如果您的模拟函数没有明确的 return_value 或 side_effect 返回,您将在 Python 尝试评估模拟的真实性时看到这一点。确保你的模拟有一个。

    要么用一个初始化它:

    item = MagicMock(return_value=True)
    

    或添加一个:

    item.return_value = True
    

    解释:

    当你做if not x:时,你可能会想到if x is False

    Python 实际上并没有这样做 - 它是 if bool(x) is False(这是 Python 的 truthiness 概念 - 值计算为 TrueFalse),而 bool(x) 实际上是致电 x.__nonzero__()(或 3.x 中的 x.__bool__())。

    这是为了提供 Python 良好的 if 行为 - 当您执行 if []: 时,许多语言会将任何对象视为 True,但 Python 旨在使代码可读,因此它委托和列表的 @ 987654334@ 方法将返回 False 如果它为空。这允许更多代码更自然地阅读,并解释为什么您会看到这些调用。

    【讨论】:

    • 这是一个奇怪的副作用 - 我得到了 dunder 机制,但这是对模拟调用返回值的 dunder 调用,而不是对模拟函数/方法本身的调用,所以它它在这里显示似乎有点令人惊讶。简单的解决方案是确保你的 mock 有一个明确的返回值 - 这些将不会出现。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-31
    • 2011-08-08
    • 1970-01-01
    • 2017-06-26
    • 1970-01-01
    相关资源
    最近更新 更多