Python - Как смоделировать более одного метода класса - PullRequest
0 голосов
/ 01 мая 2019

Я пишу новый метод внутри дочернего класса.Метод публикует объект JSON на MQTT-брокер и время ответа клиентаЧтобы выполнить его модульное тестирование, я бы хотел исправить методы (вызываемые тестируемым методом), которые публикуют сообщение json и время ответа.Без возможности имитации существует зависимость от существующего брокера MQTT и клиента для публикации ответа.Другая причина заключается в том, чтобы проанализировать аргументы (объект json), передаваемые в метод mock тестируемым методом.До сих пор я был в состоянии исправить метод класса ' init , поскольку он инициализирует многие вещи, которые мне не нужны для тестирования моего метода (регистраторы, файлы конфигурации и т. Д.).Тем не менее, когда я пытаюсь исправить другой метод в том же классе.Тестируемый метод вызывает реальный метод публикации, а не макет.Я работаю в Python 2.7 (не по выбору).Я использую себя как модуль модульного тестирования.

У меня есть функция для модульного тестирования, которая основывается на одинаковом контексте для запуска каждого сценария.Поэтому в environment.py (аналогичном confest.py в pytest) я создаю экземпляр класса один раз, чтобы пройти через всю функцию.Это отлично работает.Когда я добавляю еще один патч к методу publish_json.Он вызывает реальный метод и падает, потому что не работает MQTT-брокер.

Я также пытался насмехаться над методом publish_json с помощью MagicMock, в файле реализации шага теста.Однако это вернуло объект call (), не содержащий аргументов.

Структура классов.

BaseClass
    __init__ which i've successfully patched.
    contains the publish_json which i'm unable to patch.

    aSubClass(BaseClass)
        containing derived functionality 

        anotherSubClass(aSubClass)
            containing the new method to test.
            will eventually use the functionality within the parent classes.
# environment.py...
from anotherSubClass import anotherSubClass

def fake_pub():
        print("the fake json publisher has been called!!!")
        return True

@fixture
def anotherSubClass_mocked(context):
        # pacthing out the base class initialisation
        # patching the publish_json method which isn't working
        with patch.object(anotherSubClass, "__init__", lambda x,y,z: None), patch.object(anotherSubClass, "publish_json", fake_pub):
                context.tester = anotherSubClass(None,None)

# steps.py
@when(u'the tester sends a START message')
def step_impl(context):
    # patch the publish_json call here and validate the json contents (call_args)
    context.tester.publish_json = Mock()
    context.tester.time_mqtt_msg("START")
    args = context.tester.publish_json.call_args()

# method under test
from aSubClass import aSubClass


class anotherSubClass(aSubClass):

    def time_cloud_msg(self, msg, timeout=10):
      mqtt_msg = {"msg":"TEST", "time": self.generate_timestamp()}
      print("Sending message to remote broker")
      self.publish_json("remote", "command", mqtt_msg)
      # timer not yet implemented... :-(

Ожидается, что поддельный издатель json будетназывается.В первом случае (в среде) был вызван реальный метод публикации. Во втором случае (в шагах) предположительно был вызван макет с пустым значением (call ())

...