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

问题描述 投票:0回答:3

我正在为我们正在开发的一些库编写单元测试。该库利用

requests.post()
向外部服务器执行 POST HTTP 请求。

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

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

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

    # Some logic, irrelevant here.

    return response

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

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

    def test_foo(self):
        # Some test logic

这工作完美。

现在我想获取对我的模拟函数的调用次数。我尝试过

mocked_post.call_count
,但那不存在。我尝试在很多不同的对象(包括
mylib.requests.post
)上找到这个属性,但到目前为止还没有成功。

我如何访问这个模拟函数的

call_count

python unit-testing mocking
3个回答
97
投票

我不会在这里使用

mocked_post
作为
new
参数。我会设置一个新的 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)

现在您拥有

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)

但是,您仍然无法访问返回的

response
对象;您可能希望从
mock.DEFAULT
返回
mocked_post
,而不是在函数中创建一个,这样您就可以使用
post_mock.return_value
对返回的对象进行进一步的断言。


5
投票

9年后到来,但你也可以这样做:

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

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

        assert post_mock.call_count == 3

        #if you need to mock the return value
        post_mock.return_value = "success"

0
投票

如果您只想计算调用次数而不修改方法的行为,您可以使用

wrap
参数,如下所示:

    with mock.patch.object(FTPDownloader, 'ftp_get_stat', wraps=FTPDownloader.ftp_get_stat) as mock_ftp:

        # Your code with calls to FTPDownloader.ftp_get_stat()
        # The real ftp_get_stat() will be called as many times as necessary

        assert mock_ftp.call_count == 3

当您向

wraps
参数(使用
mock.patch.object
Mock
MagicMock
构造函数)提供对象时,它会创建一个模拟对象,该对象将所有调用委托给包装对象,同时仍然允许您对方法的调用进行计数。

© www.soinside.com 2019 - 2024. All rights reserved.