Как смоделировать вспомогательный метод для errbot

Я пытаюсь завершить свои модульные тесты для плагина errbot, который я пишу. Может ли кто-нибудь сказать мне, как смоделировать вспомогательный метод, который используется методом botcmd?

Пример:

class ChatBot(BotPlugin):

    @classmethod
    def mycommandhelper(cls):
        return 'This is my awesome commandz'

    @botcmd
    def mycommand(self, message, args):
        return self.mycommandhelper()

Как я могу издеваться над классом mycommandhelper при выполнении моего командного класса? В моем случае этот класс выполняет некоторые удаленные операции, которые не должны выполняться во время модульного тестирования.


person DidiV    schedule 25.01.2017    source источник


Ответы (2)


Очень простым/грубым способом было бы просто переопределить функцию, которая выполняет удаленные операции. Пример:

def new_command_helper(cls):
    return 'Mocked!' 

def test(self):
    ch_bot = ChatBot()
    ch_bot.mycommandhelper = new_command_helper
    # Add your test logic

Если вы хотите, чтобы этот метод имитировался во всех ваших тестах, просто сделайте это в методе setUp unittest.

def new_command_helper(cls):
    return 'Mocked!'

class Tests(unittest.TestCase):
    def setUp(self):
        ChatBot.mycommandhelper = new_command_helper
person Nether    schedule 25.01.2017
comment
Я думаю, что это сработает для «нормального» модульного тестирования, однако я не знаю, хорошо ли это сочетается с реализацией errbot для тестового бота, которая дает функциональные возможности для таких вещей, как testbot.push_message и testbot.pop_message. На самом деле, тестовый бот не импортирует издевательский класс, а скорее исходный класс и метод плагина. - person DidiV; 25.01.2017
comment
Я не могу сказать намного больше с ограниченным контекстом/кодом, который вы нам дали. Если бы вы импортировали класс, смоделировали его (изменив его переменные напрямую), а затем импортировали TestBot, он импортировал бы исходный класс, который был изменен. - person Nether; 25.01.2017
comment
Справедливости ради, проблема здесь в том, что этот конкретный фреймворк (errbot) предоставляет объект testbot, который динамически загружает свои плагины. Для этого используется extra_plugin_dir = '.' что вы можете увидеть на моем примере. Поэтому изменение класса плагина в тестовом файле не работает, потому что фреймворк загрузит немодифицированный исходный класс. Я ценю, что вы пытаетесь помочь и прикладываете усилия для этого. - person DidiV; 25.01.2017

После долгих возни, похоже, работает следующее:

class TestChatBot(object):
extra_plugin_dir = '.'

def test_command(self, testbot):
    def othermethod():
        return 'O no'
    plugin = testbot.bot.plugin_manager.get_plugin_obj_by_name('chatbot')
    with mock.patch.object(plugin, 'mycommandhelper') as mock_cmdhelper:
        mock_cmdhelper.return_value = othermethod()
        testbot.push_message('!mycommand')
        assert 'O no' in testbot.pop_message()

Хотя я считаю, что использование декораторов патчей было бы чище.

person DidiV    schedule 25.01.2017