Как синхронизировать объект Mock с целевым объектом

Я спрашиваю об управлении фиктивными объектами, независимо от конкретной реализации (EasyMock, Mock Object и т. д.).

Я не хотел использовать объект Mock в своих модульных тестах по следующей причине: поведение объекта Mock должно отражать поведение объекта, над которым издевались. Если поведение мокируемого объекта изменилось, нам также придется изменить поведение мок-объекта. Если мы этого не сделаем, поведение фиктивного объекта не будет синхронизировано с реальным объектом, что сделает модульное тестирование бессмысленным и опасным.

Мой вопрос: как синхронизировать фиктивный объект с целевым объектом? Как вы распространяете изменения? Используете ли вы какую-либо технику управления фиктивными объектами?

Изменить: изменить заголовок, чтобы сузить область.


person janetsmith    schedule 07.03.2011    source источник


Ответы (4)


Хорошо определенные API не должны иметь такого рода свободу действий: при заданном наборе входных данных имитируемый объект должен вести себя только следующим образом: поведение привязано к интерфейсу. Если допустимо отклонение, то ваш фиктивный объект должен тестировать все разные вещи, которые этот объект может делать.

Вы можете уменьшить риск дрейфа поведения, если:

  • Интеграционное тестирование и
  • Сравнение ваших фиктивных данных с реальной реализацией.
person Edward Z. Yang    schedule 07.03.2011

Я не эксперт, но я думаю, что фиктивный объект предназначен для одного тестового случая/взаимодействия. И если это взаимодействие изменится, вы, очевидно, захотите отразить это в своих тестах. Но это не должно сломать все фиктивные объекты класса, поскольку они проверяют различные взаимодействия, которые все еще могут быть действительными.

person driushkin    schedule 07.03.2011

Если ClassA вызывает:

 AThing aThing = ClassB.GiveMeAThing()

ClassA никогда не должно заботиться о том, как ClassB получает эту вещь. Таким образом, заглушка — StubB — никогда не должна заботиться о том, как ведет себя реальная реализация заглушки. StubB следует изменить только в том случае, если изменится само взаимодействие - тип возвращаемого значения или вызывающие аргументы, и это необходимо, если вы хотите, чтобы ваш код компилировался :-)

В случае, если ваш ClassB начинает возвращать Nulls или Throws новые типы исключений; Ну, тогда нужно написать совершенно новые тесты и, возможно, новые заглушки.

С уважением, Мортен

person Morten    schedule 07.03.2011

Вы на правильном пути. Вам не нужны хрупкие тесты, которые нужно менять каждый раз при рефакторинге тестируемой системы.

В основном я концентрирую свое тестирование на общедоступном интерфейсе. Если ваш общедоступный интерфейс изменится, вам, вероятно, придется изменить не только тесты.

Я также стараюсь по возможности проводить тестирование состояния вместо тестирования поведения. Поэтому я обычно использую заглушки вместо макетов. (Большинство фреймворков изоляции/насмешек позволят вам создать и то, и другое.) Я проверяю состояние тестируемой системы (или класса), а не прошу фиктивный объект проверить себя.

Тем не менее, я стараюсь быть гибким. Если тестирование фиктивного поведения имеет смысл в данном случае, я буду использовать его. Если мне нужно обнажить внутренности, чтобы получить достойное освещение, я это сделаю.

РЕДАКТИРОВАНИЕ: см. также эту статью Скотта Бэйна.

person TrueWill    schedule 07.03.2011