【问题标题】:With unittest.mock, how do you mock a method of a member field?使用 unittest.mock,如何模拟成员字段的方法?
【发布时间】:2020-10-20 14:54:50
【问题描述】:

我正在使用 Python 3.8。我有一个带有成员字段的类...

class AbcServiceBus:

    def __init__(self, ...):
        ...
        self._service_bus = AzureServiceBus()

    def send_insert_notification(self, record_id):
        message_json = {'ids': [record_id]} 
        self._service_bus.send_topic_message(
            namespace_name=self._namespace,
            topic_name=self._topic_name, 
            message_json=message_json
        )  
        return True

我想模拟成员字段的“send_topic_message”方法。我尝试了以下

from unittest import mock
...

    sb = AbcServiceBus(device)
    with mock.patch('common.azure_service_bus.AzureServiceBus.send_topic_message') as send_topic_message_mock:
        sb.send_insert_notification(record_id)
        send_topic_message_mock.assert_called_with(
            sb._namespace, 
            sb._topic_name, 
            {'ids': [record_id]}
        )

但这继续调用类的真实方法,而不是我设置的模拟。模拟成员字段方法的正确方法是什么?

【问题讨论】:

  • 看起来你没有修补AzureServiceBus where it is used - 你需要修补using_module.AzureServiceBus.send_topic_message

标签: python-3.x unit-testing mocking pytest python-mock


【解决方案1】:

我将模拟 AzureServiceBus 类。在模拟AzureServiceBus 类之后创建AbcServiceBus 的实例,以便我们可以使用AzureServiceBus 的模拟版本

azure_service_bus.py:

from azure.servicebus.control_client import ServiceBusService as AzureServiceBus


class AbcServiceBus:

    def __init__(self):
        self._namespace = '_namespace'
        self._topic_name = '_topic_name'
        self._service_bus = AzureServiceBus()

    def send_insert_notification(self, record_id):
        message_json = {'ids': [record_id]}
        self._service_bus.send_topic_message(
            namespace_name=self._namespace,
            topic_name=self._topic_name,
            message_json=message_json
        )
        return True

test_azure_service_bus.py:

import unittest
from unittest import mock
from azure_service_bus import AbcServiceBus


class TestAbcServiceBus(unittest.TestCase):
    def test_send_insert_notification(self):
        record_id = '1'

        with mock.patch('azure_service_bus.AzureServiceBus') as mock_AzureServiceBus:
            mock_AzureServiceBus_instance = mock_AzureServiceBus.return_value
            sb = AbcServiceBus()
            actual = sb.send_insert_notification(record_id)
            self.assertTrue(actual)
            mock_AzureServiceBus.assert_called_once()
            mock_AzureServiceBus_instance.send_topic_message.assert_called_with(
                namespace_name='_namespace',
                topic_name='_topic_name',
                message_json={'ids': ['1']}
            )


if __name__ == '__main__':
    unittest.main()

单元测试结果:

.
----------------------------------------------------------------------
Ran 1 test in 0.002s

OK
Name                                                   Stmts   Miss  Cover   Missing
------------------------------------------------------------------------------------
src/stackoverflow/64447772/azure_service_bus.py           10      0   100%
src/stackoverflow/64447772/test_azure_service_bus.py      15      0   100%
------------------------------------------------------------------------------------
TOTAL                                                     25      0   100%

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-23
    • 2017-05-29
    • 1970-01-01
    • 1970-01-01
    • 2018-07-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多