Макетный экземпляр, созданный из класса, хранящегося в переменной - PullRequest
0 голосов
/ 29 октября 2018

У меня есть следующий код:

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 на Mock или Mock(). Если я отлаживаю то, что возвращает message_class(body), это Mock, но я не могу получить экземпляр и утверждать его (потому что Mock, который я назначаю в моем тесте, не используется, это тип) .
  2. Патч Message класс с декоратором. Всякий раз, когда я делаю это, кажется, что это не ловит это. Когда я отлаживаю то, что message_class(body) возвращает его типа Message, а не Mock.
  3. Попробуйте смоделировать __init__ метод message_class в надежде, что я смогу установить экземпляр, который возвращается всякий раз, когда код пытается создать сообщение. Не работает, выдает ошибки, потому что метод __init__ не предполагает возвращаемого значения.

1 Ответ

0 голосов
/ 29 октября 2018

Если бы вы хранили реальный экземпляр, я бы сказал, что вы могли бы сделать что-то вроде 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()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...