как избежать возврата макетов из списка макетов - PullRequest
14 голосов
/ 20 апреля 2010

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

Примером может служить объект, который проверяет, оплачиваются ли счета за прошлый месяц. Ему нужен сервис, который извлекает список счетов. Поэтому мне нужно смоделировать этот billRetrievalService в моих тестах. В то же время мне нужно, чтобы BillRetrievalMock возвращал поддельные счета (поскольку я не хочу, чтобы мой тест полагался на правильность реализации счета).

Мой дизайн имеет недостатки? Есть ли лучший способ проверить это? Или это так, как должно быть при использовании объектов поиска (в данном случае - поиск счетов)?

примечание: несмотря на то, что Билл может быть кандидатом на объект значения, более широкая проблема остается, когда коллекции не содержат объектов значения (например, пользователей).

Ответы [ 4 ]

13 голосов
/ 15 мая 2012

В большинстве случаев, если мне нужно издеваться над другим издеванием, я нахожу зависимость, которая имеет больше смысла в другом направлении. Иными словами, mock-returning-mock обычно указывает на нарушение принципа обращения зависимостей.

Одно распространенное исключение: фабрика, которая создает объекты (в отличие от «держателя», который просто возвращает один и тот же объект каждый раз). Если мне нужно создать несколько объектов одного типа в течение моей жизни, тогда мне может понадобиться ObjectFactory и вызвать #createObject(), а затем, возможно, установить ожидания для объектов. Тем не менее, я бы поставил под сомнение это. Возможно, что-то еще на один уровень вверх по стеку вызовов создаст для меня Object s и выдаст их мне по мере необходимости.

В случае ObjectHolder, вместо того, чтобы Object получать *1010*, я предпочитаю напрямую зависеть от Object и заставлять моего абонента отдавать его мне так, как ему хочется. Это учитывает желаемое свойство дизайна независимость от контекста .

Одной из конкретных версий этой проблемы является шаблон «Виртуальные часы». Иногда вам нужно зависеть от виртуальных часов, но часто лучше просто запросить временную метку (шаблон «Мгновенный запрос») или, в худшем случае, поток временных меток, откуда бы они ни исходили. Тесты могут предоставить управляемый поток удобных жестко закодированных временных меток, но также легко превратить системные часы в поток временных меток.

11 голосов
/ 21 апреля 2010

Ложные возвратные шутки - это сильный запах кода - возможная проблема с дизайном. Могло случиться так, что векселя должны быть неизменными значениями объектов, которые не должны подвергаться насмешкам. Или есть некоторая путаница с дизайном и обязанностями классов.

Книга Выращивание объектно-ориентированного программного обеспечения, руководствуясь тестами и бумага Ложные роли, а не объекты от изобретателей ложных объектов заслуживают чтения.

5 голосов
/ 08 мая 2010

Как подсказывает Путь Testuvius , ни один принцип, пусть и хороший, не следует принимать абсолютно, и поэтому с правилом, что вам не нужны насмешки, возвращающие насмешки, бывают случаи, когда это вполне подходит.

Как предполагает Гутзофтер, вы можете разбить свой объект на две части: одну для фактической проверки, а другую для получения счетов для проверки. Преимущество применения принципа «единственная ответственность» состоит в том, что валидатор будет более универсальным и пригодным для повторного использования. С другой стороны, если у вас есть только этот простой вариант использования и нет особой необходимости в более высокой возможности повторного использования, очень прагматично хранить поиск и проверку в одном классе. Расслоение, взрыв числа объектов и т. Д., Не оправданные реальной потребностью и реальной выгодой, осуществляемые только ради удовлетворения абстрактного принципа, не годятся. Вы всегда должны взвесить все за и против, а реальность редко бывает простой и прекрасной, как хотелось бы :-) Прекрасные примеры этого прагматического подхода можно найти в шаблонах Аэма Бьена для реального мира Java EE - переосмысление лучших практик.

4 голосов
/ 22 апреля 2010

Обычно, когда я высмеиваюсь, у меня появляется триада объектов. Первый объект будет координатором BillsPaidLastMonthCoordinator этот объект имеет две зависимости BillRetrievalService и BillPaidValidator.

Вы бы высмеяли две зависимости, и ваш тест был бы для взаимодействия извлечения и передачи счетов для проверки. Так что для этого теста вам будет все равно, что это за данные. Это помогает разделить обязанности. Ваш исходный объект был ответственен за получение Bills, а затем за проверку, был ли это счет isPaid.

С тем, как вы описали проблему, вы можете получить шумный и хрупкий тест. Хрупкость возникает из-за того, что она может быть сломана двумя способами.

С помощью corrdinator его не нужно менять, если изменяется реализация Bill, просто объекты, которые на самом деле используют Bill. Мои 2 сентаво.

[EDIT]

Это больше соответствует использованию обработчиков событий (координатор)

...