Python mock call_args_list为参数断言解包元组

2024-05-10 07:21:47 发布

您现在位置:Python中文网/ 问答频道 /正文

我在处理Mock.call_args_list返回的嵌套元组时遇到了一些问题。

def test_foo(self):
    def foo(fn):
        fn('PASS and some other stuff')

    f = Mock()
    foo(f)
    foo(f)
    foo(f)

    for call in f.call_args_list:
        for args in call:
            for arg in args:
                self.assertTrue(arg.startswith('PASS'))

我想知道是否有更好的方法来解包mock对象上的call_args_列表,以便做出我的断言。这个循环是有效的,但感觉一定有一个更直接的前进方向。


Tags: andintestselfforfoodefarg
1条回答
网友
1楼 · 发布于 2024-05-10 07:21:47

一个更好的方法可能是建立预期的自我调用,然后使用直接断言:

>>> from mock import call, Mock
>>> f = Mock()
>>> f('first call')
<Mock name='mock()' id='31270416'>
>>> f('second call')
<Mock name='mock()' id='31270416'>
>>> expected_calls = [call(s + ' call') for s in ('first', 'second')]
>>> f.assert_has_calls(expected_calls)

请注意,调用必须是连续的,如果不希望这样,则重写断言的any_orderkwarg。

还要注意,允许在 指定的调用。如果不需要,则需要添加另一个断言:

>>> assert f.call_count == len(expected_calls)

针对mgilson的注释,下面是创建可用于通配符相等性比较的虚拟对象的示例:

>>> class AnySuffix(object):
...     def __eq__(self, other):
...         try:
...             return other.startswith('PASS')
...         except Exception:
...             return False
...        
>>> f = Mock()
>>> f('PASS and some other stuff')
<Mock name='mock()' id='28717456'>
>>> f('PASS more stuff')
<Mock name='mock()' id='28717456'>
>>> f("PASS blah blah don't care")
<Mock name='mock()' id='28717456'>
>>> expected_calls = [call(AnySuffix())]*3
>>> f.assert_has_calls(expected_calls)

以及故障模式示例:

>>> Mock().assert_has_calls(expected_calls)
AssertionError: Calls not found.
Expected: [call(<__main__.AnySuffix object at 0x1f6d750>),
 call(<__main__.AnySuffix object at 0x1f6d750>),
 call(<__main__.AnySuffix object at 0x1f6d750>)]
Actual: []

相关问题 更多 >