Commit a0f35732 authored by Nitanshu's avatar Nitanshu Committed by Guillaume Binet (argo.ai)

TestBot: Implement inject_mocks method (#1235)

Method to inject property in the plugin
object and discard the existing
assignments.
parent 57422b89
......@@ -121,6 +121,39 @@ What we need now is get access to the instance of our plugin itself. Fortunately
There we go, we first grab out plugin thanks to a helper method on :mod:`~errbot.plugin_manager` and then simply execute the method and compare what we get with what we expect. You can also access `@classmethod` or `@staticmethod` methods this way, you just don't have to.
Sometimes a helper method will be making HTTP or API requests which might not be possible to test directly. In that case, we need to mock that particular method and make it return the expected value without actually making the request.
.. code-block:: python
URL = 'http://errbot.io'
class MyPlugin(BotPlugin):
@botcmd
def mycommand(self, message, args):
return self.mycommand_helper()
def mycommand_helper(self):
return (requests.get(URL).status_code)
What we need now is to somehow replace the method making the request with our mock object and `inject_mocks` method comes in handy.
Refer `unittest.mock <https://docs.python.org/3/library/unittest.mock.html>`_ for more information about mock.
.. code-block:: python
from unittest.mock import MagicMock
extra_plugin_dir = '.'
def test_mycommand_helper(testbot):
helper_mock = MagicMock(return_value='200')
mock_dict = {'mycommand_helper': helper_mock}
testbot.inject_mocks('MyPlugin', mock_dict)
testbot.push_message('!mycommand')
expected = '200'
result = testbot.pop_message()
assert result == expected
Pattern
-------
......
......@@ -461,6 +461,25 @@ class TestBot(object):
self.bot.push_message(command)
assert 'not found' not in self.bot.pop_message(timeout)
def inject_mocks(self, plugin_name: str, mock_dict: dict):
"""Inject mock objects into the plugin
mock_dict = {
'field_1': obj_1,
'field_2': obj_2,
}
testbot.inject_mocks(HelloWorld, mock_dict)
assert 'blah' in testbot.exec_command('!hello')
"""
plugin = self.bot.plugin_manager.get_plugin_obj_by_name(plugin_name)
if plugin is None:
raise Exception(f'"{PluginName}" is not loaded.')
for field, mock_obj in mock_dict.items():
if not hasattr(plugin, field):
raise ValueError(f'No property/attribute named "{field}" attached.')
setattr(plugin, field, mock_obj)
class FullStackTest(unittest.TestCase, TestBot):
"""
......
......@@ -6,6 +6,7 @@ from os import path, mkdir
from queue import Empty
from shutil import rmtree
from tempfile import mkdtemp
from mock import MagicMock
import pytest
import tarfile
......@@ -355,3 +356,11 @@ def test_command_not_found_with_space_in_bot_prefix(testbot):
testbot.bot_config.BOT_PREFIX = '! '
assert 'Command "blah" not found.' in testbot.exec_command('! blah')
assert 'Command "blah" / "blah toto" not found.' in testbot.exec_command('! blah toto')
def test_mock_injection(testbot):
helper_mock = MagicMock()
helper_mock.return_value = 'foo'
mock_dict = {'helper_method': helper_mock}
testbot.inject_mocks('Dummy', mock_dict)
assert 'foo' in testbot.exec_command('!baz')
......@@ -29,3 +29,11 @@ class DummyTest(BotPlugin):
def run_lots_of_subcommands(self, msg, args):
"""Tests multiple subcommands"""
return args
def helper_method(self, arg):
return arg
@botcmd
def baz(self, msg, args):
"""Tests mock injection method"""
return self.helper_method('baz')
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment