首页 > 解决方案 > 从存储在变量中的类创建的模拟实例

问题描述

我有以下代码:

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_classMockMock()。如果我调试message_class(body)返回的内容,它是一个 Mock,但我似乎无法获取实例并对其进行断言(因为我在测试中分配的 Mock 不是使用的实例,而是类型)。
  2. Message带有装饰器的补丁类。每当我这样做时,它似乎都没有抓住它。当我调试message_class(body)返回其Message类型而不是 Mock 的内容时。
  3. 尝试模拟 的__init__方法,message_class希望我可以设置在代码尝试实例化消息时返回的实例。不起作用,抛出错误,因为该__init__方法不应该有返回值。

标签: pythonunit-testingmocking

解决方案


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

信使。请注意分配message_class给自我的轻微修改。我假设您打算这样做,否则如果没有一些全球性的时髦,它将无法工作:

'''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()

推荐阅读