Python 模拟对同一方法的多个调用时,如何断言调用顺序和参数?

Python 模拟对同一方法的多个调用时,如何断言调用顺序和参数?,python,unit-testing,mocking,Python,Unit Testing,Mocking,我对同一个mock有多个调用,我想检查每个调用的参数和调用顺序 例如,如果我需要检查最后一次通话,我会使用以下方法: mock.assert_called_once_with( 'GET', 'https://www.foobar.com', params=OrderedDict([ ('email', 'email'), ]), headers=None, data=None) 但是,我想为每个电话都这样做 我做到了,就像这样

我对同一个mock有多个调用,我想检查每个调用的参数和调用顺序

例如,如果我需要检查最后一次通话,我会使用以下方法:

mock.assert_called_once_with(
    'GET',
    'https://www.foobar.com',
    params=OrderedDict([
        ('email', 'email'),
    ]),
    headers=None, 
    data=None)
但是,我想为每个电话都这样做

我做到了,就像这样:

mycode.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
test_mycode.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方法。我觉得有更好的方法。我对mocking还是一个新手,所以任何建议都将不胜感激。

您可能想使用这种方法


默认情况下,
assert\u has\u calls
将检查调用的顺序是否正确。如果您不关心顺序,您可以使用
任意顺序
关键字参数(设置为
True
)。

这对我不起作用,因为显然在POST和GET之间还有其他调用<代码>[呼叫('POST','https://api.stormpath.com/v1/challenges/challenge_id,allow_redirects=False,data='{“code”:“000000”},headers=None,params=None),call().status_code.状态代码.状态代码.状态代码.状态代码.状态代码(‘得到’,’https://api.stormpath.com/v1/challenges/challenge_id“,允许_redirects=False,data=None,headers=None,params=None)],@BoldMarshmallow我认为为了正确地隔离您试图测试的内容,您需要模拟更多的东西。@BoldMarshmallow——而且,您还没有实际显示您的真实代码。例如,
Foo.req
引用从未定义过的
self
。显然有更多内容(可能在您的框架内)比你在这里展示的要多。是的,这是故意的。遗憾的是,出于隐私原因,我不能透露更多的代码。无论如何,我还是要感谢你的尝试。
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)
])