如何使用Mock @patch获取通话计数?

ere*_*eOn 26 python unit-testing mocking

我正在为我们正在研究的一些图书馆编写单元测试.该库用于对requests.post()外部服务器执行POST HTTP请求.

在我的UT内部,我显然不想联系真实的服务器,而是模拟响应.

为此,我编写了一个函数,如下所示:

def mocked_post(url, headers, data, **kwargs):
    response = Mock()

    # Some logic, irrelevant here.

    return response
Run Code Online (Sandbox Code Playgroud)

我在我的单元测试类中修补了这个函数:

@patch('mylib.requests.post', mocked_post)
class MyTest(TestCase):

    def test_foo(self):
        # Some test logic
Run Code Online (Sandbox Code Playgroud)

这很完美.

现在我想获得对我的模拟函数的调用次数.我尝试mocked_post.call_count但不存在.我试图在很多不同的对象(包括mylib.requests.post)上找到这个属性,但到目前为止还没有运气.

如何访问call_count此模拟函数?

Mar*_*ers 54

我不会mocked_postnew这里作为论据.我设置了一个新鲜的side_effect属性Mock:

@patch('mylib.requests.post')
class MyTest(TestCase):

    def test_foo(self, post_mock):
        post_mock.side_effect = mocked_post

        # Some test logic

        self.assertEqual(post_mock.call_count, 3)
Run Code Online (Sandbox Code Playgroud)

现在,您拥有为您生成的Mock对象,patch作为所有测试方法的参数,您可以测试模拟被调用的次数.

您也应该能够side_effect在装饰器中设置属性,以应用于所有测试:

@patch('mylib.requests.post', side_effect=mocked_post)
class MyTest(TestCase):

    def test_foo(self, post_mock):
        # Some test logic

        self.assertEqual(post_mock.call_count, 3)
Run Code Online (Sandbox Code Playgroud)

但是,您仍然无法访问返回的response对象; 您可能需要返回mock.DEFAULTmocked_post,而不是创建一个在功能,这样就可以再使用post_mock.return_value,以使返回的对象上进一步断言.

  • 这确实很完美.非常感谢.但是,我不确定为什么我们必须将`mocked_post`影响到名为`side_effect`的东西.对我来说似乎不是*副作用*,而是像被模拟对象的主要目的.我错过了什么吗? (2认同)