python - 模拟对同一方法的多次调用时如何断言调用顺序和参数?

标签 python unit-testing mocking

我多次调用同一个模拟,我想检查每个调用参数和调用顺序。

例如如果我只需要检查最后一次通话,我会使用这个:

mock.assert_called_once_with(
    'GET',
    'https://www.foobar.com',
    params=OrderedDict([
        ('email', 'email'),
    ]),
    headers=None, 
    data=None)

但是我想为每次通话都这样做。

我已经设法做到了,就像这样:

我的代码.py

from requests import Session

class Foo(object):

    def req(method, url, data, params=None, headers=None):
        self.session = Session()
        r = self.session.request(method, url, data=data, params=params, headers=headers)
        return r

测试代码.py

@patch('myapp.mycode.Session')
def test_foobar(self, Session):
    # Set mock.
    self.request_mock = Session.return_value.request
    self.request_mock.return_value = MagicMock()

    data = {'foo': 'bar'}
    f = Foo()
    f.req('POST', 'https://www.foobar.com/', data=data)
    f.req('GET', 'https://www.foobar.com/', data=None)


    self.assertEqual(self.request_mock.call_count, 2)
    call1 = self.request_mock._mock_call_args_list[0]
    call2 = self.request_mock._mock_call_args_list[1]

    call_params = (
        ('POST', 'https://www.foobar.com'),
        {
            'headers': None,
            'allow_redirects': False,
            'params': None,
            'data': json.dumps(data)
        }
    )
    self.assertEqual(tuple(call1), call_params)

    call_params = (
        ('GET', 'https://www.foobar.com'),
        {
            'headers': None,
            'allow_redirects': False,
            'params': None,
            'data': None
        }
    )
    self.assertEqual(tuple(call2), call_params)

这可行,但我有点担心调用参数上的 assertEqual 方法。我觉得有更好的方法可以做到这一点。我对模拟还很陌生,所以任何建议都将不胜感激。

最佳答案

您可能想使用 Mock.assert_has_calls方法。

self.assertEqual(self.request_mock.call_count, 2)
self.request_mock.assert_has_calls([
    mock.call(
        'POST',
        'https://www.foobar.com',
        headers=None,
        allow_redirects=False,
        params=None,
        data=json.dumps(data)),
    mock.call(
        'GET',
        'https://www.foobar.com',
        headers=None,
        allow_redirects=False,
        params=None,
        data=None)
])

默认情况下,assert_has_calls 将检查调用是否以正确的顺序发生。如果您不关心顺序,可以使用 any_order 关键字参数(设置为 True)。

关于python - 模拟对同一方法的多次调用时如何断言调用顺序和参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40136811/

相关文章:

c# - Rhino Mocks 模拟 WindowsImpersonationContext

Python - 如果给定字典,则按值的顺序创建键列表

python - python (2.7) unittest 的测试描述如何修改

rest - 在模拟服务 URL 中使用通配符

javascript - 使用 Jasmine 监视整个实例的任何方法

unit-testing - 单元测试:要测试什么/什么不能测试?

php - 当最初 stub 的方法不存在时,PHPUnit失败

python - 将python脚本输出输出到文件时出现Unicode错误

python - PyQt4 - 无法接收 sender() 信号/如何识别单击了哪个按钮并将其与适当的进度条匹配?

python - 在一台机器上的 celery worker 之间共享内存区域