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

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

最佳答案

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

信使。请注意将 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()

关于python - 从存储在变量中的类创建的模拟实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53040670/

相关文章:

python - Ant 模拟: it's better to create a Process/Thread for each Ant or something else?

python - 比较两个列表并只打印差异? (异或两个列表)

ruby-on-rails-3 - 使用 RSpec 将参数传递给 Rails Controller 操作中的模拟模型方法的问题

unit-testing - 什么时候使用 stub 和模拟?

Python:解码问题(ascii)

python - PyGame 不断崩溃,我不知道为什么

android - 由于 App not Idle 异常 : The following Idle Conditions failed ASYNC_TASKS_HAVE_IDLED,Espresso 测试失败

c# - NUnit 断言方法错误也在 NUnit.Framework 和 Microsoft.VisualStudio.TestTools.UnitTesting 命名空间中找到

unit-testing - Realm.io 迁移的 RealmSwift 单元测试

c# - Moq - 模拟通用存储库