从存储在变量中的类创建的模拟实例

时间:2018-10-29 07:27:08

标签: python unit-testing mocking

我有以下代码:

class Messenger(object):
    def __init__(self):
        # Class Type of what messages will be created as.
        message_class = Message

    def publish(self, body):
        # Instantiate object of type stored in `message_class`
        message = message_class(body)
        message.publish()

我想断言Message.publish()方法已被调用。我该如何实现?

我已经尝试了以下方法:

  1. message_class分配给MockMock()。如果我调试message_class(body)返回的内容,则它是一个Mock,但我似乎无法获取该实例并对其进行断言(因为我在测试中分配的Mock不是所用的实例,因此它是类型)。
  2. 使用装饰器修补Message类。每当我这样做时,似乎都无法抓住它。当我调试message_class(body)返回的是Message类型而不是Mock时。
  3. 尝试模拟__init__的{​​{1}}方法,希望我可以设置代码尝试实例化消息时返回的实例。不起作用,因为message_class方法不应具有返回值而引发错误。

1 个答案:

答案 0 :(得分:0)

如果您要存储实际的实例,我想说您可以做类似messenger.message.publish.assert_called_once的事情,但是由于存储了message_class,所以它有点棘手。鉴于此,您可以从模拟的return_value中提取class并以这种方式检查调用。这是我的操作方式:

信使。请注意将message_class分配给self的微小修改。我假设您打算这样做,否则如果没有一些全球性的创新就无法正常工作:

'''messenger.py'''
class Message(object):
    def __init__(self, body):
        self.body = body

    def publish(self):
        print('message published: {}'.format(self.body))


class Messenger(object):
    def __init__(self):
        # Class Type of what messages will be created as.
        self.message_class = Message

    def publish(self, body):
        # Instantiate object of type stored in `message_class`
        message = self.message_class(body)
        message.publish()

测试:

'''test_messenger.py'''    
from unittest import mock, TestCase

from messenger import Messenger

class TestMessenger(TestCase):
    @mock.patch('messenger.Message')
    def test_publish(self, mock_message):
        messenger = Messenger()
        messenger.publish('test body')
        # .return_value gives the mock instance, from there you can make your assertions
        mock_message.return_value.publish.assert_called_once()