Easymock частично издевается (EasyMock ClassExtension), хорошо или плохо? - PullRequest
3 голосов
/ 19 ноября 2009

Я написал довольно много Mock-объектов, используя EasyMock. Тем не менее, часто я считаю, что написание частичных издевательств отнимает много времени, и это не кажется «правильным».

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

Что ты думаешь? Частично издеваться - это хорошо или плохо? И если хорошо / плохо, почему? Что бы вы посоветовали, если заметите, что не можете смоделировать объект, потому что хотите использовать только несколько методов?

Ответы [ 3 ]

4 голосов
/ 19 ноября 2009

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

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

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

0 голосов
/ 08 сентября 2011

Мое мнение таково: частичная насмешка хороша, особенно когда вы:

• фиктивные методы, которые вызывают методы JNI, например

public void methodToTest() {
    int result = invokeLibraryCode();
}

// This method will be mocked
int invokeLibraryCode() {
    // This method is native:
    com.3rdparty.Library.invokeMethod(); 
}

• фиктивные методы, которые работают с текущей датой, в то время как вам нужно контролировать дату:

public void methodToTest() {
    Calendar cal = getCurrentDate();
}

// This method will be mocked
Calendar getCurrentDate() {
    return Calendar.getInstance();
}

• mock InputStream, Process и другие абстрактные классы:

public void methodToTest(InputStream is) throws IOException {
    int i = is.read(); // is.read() is mocked
}

Конечно, вы можете покрыть первые два случая с помощью интерфейса (обернуть com.3rdparty.Library в свой собственный интерфейс, внедрить CurrentDateProvider и т. Д., Но я думаю, что это усложняет вещи).

0 голосов
/ 19 ноября 2009

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

Я запутался в том, что вы подразумеваете под "вы хотите издеваться только над несколькими методами". Какую версию EasyMock вы используете? Как правило, вам нужно только указать ожидания и вернуть значения для методов, которые будут фактически вызываться. Или вы имеете в виду, что пишете окурки этих классов?

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

...