У меня возникла ситуация, когда мне нужно имитировать некоторый производственный код. Это сделано для того, чтобы одна часть кода работала наполовину.

Мне нужно написать пустые классы (для реализации интерфейса) или использовать имитирующую систему, такую ​​как moq.

Итак, вопрос в том, снижают ли имитирующие системы производительность или ухудшают читаемость производственного кода?

обновить
пример:

interface IRocketSystem
{
   void LaunchTheRocket();
}

class SimulationRocketSystem:IRocketSystem
{
...
}

class RocketSystem:IRocketSystem
{
...
}

Я обнаружил, что у меня есть классы SimulationRocketSystem в производстве, такие маленькие и не очень много в теле. у макетной системы есть одна строка кода ( new Mock (). Object ) для замены подобных классов.

Плюсы насмешек:
меньше пустых классов в проекте.

12
Avram 31 Июл 2009 в 13:56

8 ответов

Лучший ответ

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

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

Во-вторых, вы должны учитывать, что произойдет, если кто-то изменит интерфейс. Что делать, если метод добавлен? Должен ли он по умолчанию возвращать null - как поступили бы некоторые фреймворки? Что, если метод должен вернуть какое-то конкретное возвращаемое значение в соответствии с контрактом интерфейса. Если у вас есть конкретная реализация, то компилятор хоть в какой-то мере вас защитит. Если вы используете фиктивный фреймворк, вам может не повезти.

13
waxwing 2 Авг 2009 в 19:32

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

Поскольку вы в конечном итоге реализуете рассматриваемый класс, было бы мало смысла иметь фиктивную структуру, делающую это за вас, ИМО. Почему бы просто не создать класс и не реализовать его по мере необходимости.

9
Brian Rasmussen 3 Авг 2009 в 05:21

Что не так с пустым классом?

Действительно, он будет заменен реальным классом, так что вы можете начать с настоящего класса.

Я считаю, что размещение фиктивного кода любого рода вне тестов - плохая политика.

6
S.Lott 31 Июл 2009 в 10:07

Вы называете это притворством, но похоже, что то, что вы делаете, - это просто правильное разделение забот.

Использование полиморфизма if-операторов для контроля над тем, что должно произойти, - это хорошо.

Например, скажем, если вы хотите, чтобы ведение журнала было необязательным. Обязательный подход - предоставить boolean isLogging. Затем каждый раз проверяйте логическое значение, например if (isLogging) { ...logging code... }.

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

Это просто хорошее объектно-ориентированное программирование.

2
Christian 2 Авг 2009 в 14:42

Возможно, это немного необычно, поэтому в своих комментариях и т. Д. Я бы пояснил, что это необходимая функциональность. В противном случае кто-то будет очень сбит с толку относительно того, как тестовый код попал в рабочую среду!

Что касается производительности, ее, как всегда, нужно измерить, поскольку она настолько специфична. Однако я рискну предположить, что, поскольку вы имитируете функциональность, которую не написали, она вполне может быть намного быстрее , чем ваша смоделированная реализация. Возможно, вам придется проинформировать своих пользователей об этом, поскольку, когда вы предоставляете окончательную работоспособную реализацию, они вполне могут увидеть снижение производительности :-)

Настоящее решение - предоставить фиктивную реализацию существующему интерфейсу и предоставить реальную реализацию позже.

2
Brian Agnew 2 Авг 2009 в 18:51

Я действительно не знаю о проблемах с производительностью. Но ИМХО, вы должны быть очень осторожны с удобочитаемостью. Не лучше ли объявить один или несколько интерфейсов и реализовать их двумя разными способами?

--РЕДАКТИРОВАТЬ

Мокинг может быть проще и требует меньше строк кода, но увеличивает время обучения вашему коду. Если новый парень придет и увидит ваш код, ему потребуется больше времени, чтобы понять. Лично я считаю, что это еще не реализованная функция кода. Но если бы существовала другая реализация интерфейса или какое-то другое хорошее дизайнерское решение, я бы «получил» гораздо быстрее и чувствовал бы себя более защищенным при изменении кода.

Что ж, это личное мнение. Ваш код будет использовать другой шаблон, чем ожидалось. Это похоже на «соглашение по конфигурации». Если вы не используете соглашение, вам будет сложнее его настроить (в вашем случае документировать и прояснить, что вы делаете).

1
Samuel Carrijo 31 Июл 2009 в 12:21

Мой совет - не запускайте его в производство. Никогда не вводите в производство ничего, что может замедлить, сломать или иным образом привести к потере работы :)

Но важнее того, что я думаю, какова политика вашей компании и что думает ваш менеджер? Никогда не думайте о принятии такого решения самостоятельно - это называется CYA.

1
Larry Watanabe 31 Июл 2009 в 12:25

Мне нужно написать пустые классы или использовать имитирующую систему, такую ​​как moq.

Обернуть его в специальный компонент фасада / адаптера и использовать внутренние классы должно быть достаточно. Если ваши пустые классы нужно передавать по системе, у вас проблема.

-1
pmf 31 Июл 2009 в 10:20