Сравнение между Mockito и JMockit-почему Mockito проголосовал лучше, чем JMockit? [закрытый]


Я исследую, какие насмешливые рамки использовать для моего проекта и сузили его до JMockit и Mockito.

Я заметил, что Mockito был признан "лучший макет рамки для Java " на Stackoverflow.
При сравнении возможностей на JMockit 's"Насмешливая Матрица Сравнения Инструментов" похоже, что JMockit имеет несколько различных особенности.

У кого-нибудь есть конкретная информация (не мнения) о том, что Mockito может сделать то, что не может быть достигнуто с JMockit и наоборот?

5 112

5 ответов:

Я бы сказал, что конкуренция между JMockit и PowerMock, потом Mockito.

Я бы оставил "простой" jMock и EasyMock, потому что они используют только proxy & CGLIB и не используют инструментарий Java 5, как новые фреймворки.

у jMock также не было стабильного выпуска более 4 лет. jMock 2.6.0 потребовалось 2 года, чтобы перейти от RC1 к RC2, а затем еще 2 года, прежде чем он действительно был выпущен.

в отношении Прокси & CGLIB vs instrumentation:

(EasyMock и jMock) основаны на java.ленг.отражать.Полномочие, который требует, чтобы интерфейс был выполненный. Кроме того, они поддержка создания макетных объектов для классов через подкласс CGLIB поколение. Из-за этого, сказал занятия не могут быть окончательными и только переопределяемые методы экземпляра могут быть издевавшийся. Самое главное, однако, при использовании этих инструментов зависимости тестируемого кода (что есть объекты других классов на данного тестируемого класса зависит) должно быть проконтролировано тесты, так что макетные экземпляры могут быть передано клиентам тех зависимости. Следовательно, зависимости нельзя просто создать экземпляр с помощью новый оператор в клиентском классе для который мы хотим написать модульные тесты.

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

  1. каждый класс, который может потребоваться высмеять в тесте, должен либо реализовать отдельный интерфейс или не быть окончательным.
  2. зависимости каждого тестируемого класса должны быть либо получены через конфигурируемое создание экземпляра методы (фабрики или сервис Локатор), или быть выставлены для зависимости инъекция. В противном случае модульные тесты не будут иметь возможность передавать макетные реализации зависимостей к блоку под тест.
  3. так как только экземпляр методы могут быть издевались, классы для модульного тестирования не удается вызвать статические методы их зависимости, ни инстанцировать их использует любой из конструкторов.

выше скопировано из http://jmockit.org/about.html . Кроме того, он сравнивает между собой (JMockit), PowerMock и Mockito несколькими способами:

теперь есть другие насмешливые инструменты для Java, которые также преодолевают ограничения обычного права те, между ними PowerMock, jEasyTest, и MockInject. Тот, что ближе всего к набору функций JMockit относится PowerMock, поэтому я кратко оценю он здесь (кроме того, два других более ограниченный и, кажется, не будет активно развивался уже).

JMockit против PowerMock

  • во-первых, PowerMock не предоставляет полный API для насмешек, но вместо этого работает как расширение еще один инструмент, который в настоящее время может быть EasyMock или Mockito. Это очевидно преимущество для существующих пользователей этот инструмент.
  • JMockit, с другой стороны, предоставляет совершенно новые API, хотя его основной API (ожидания) аналогичен как jMock и EasyMock. Пока это создает более длинную кривую обучения, также позволяет JMockit, чтобы обеспечить проще, последовательнее и проще использовать API.
  • по сравнению с JMockit API для ожидания, PowerMock API является более "низкий уровень", заставляя пользователям выясните и укажите, какие классы нужно быть готовым к тестированию (с @PrepareForTest ({ClassA.класс, ...}) аннотация) и требующий конкретные вызовы API для обработки различные виды языковых конструкций что может присутствовать в производстве код: статические методы (mockStatic (ClassA.класс)), проектировщики (подавить (конструктор (ClassXyz.класс))), вызовы конструктора (expectNew (AClass.класс)) частичная издевается (createPartialMock (ClassX.класс, "methodToMock")) и др.
  • С ожиданиями JMockit, все виды методов и конструкторов издевались в чисто декларативным способом, с частичным издевательством, указанным через регулярные выражения в @Mocked аннотация или просто " без насмешек" участники без записей ожидания; то есть, разработчик просто объявляет какой-то общий " макет поля " для тестового класса, или некоторые "локальные фиктивные поля" и / или "макет параметры " для индивидуального испытания методы (и в в этом последнем случае @Издевались аннотации часто не будет необходимый.)
  • некоторые возможности, доступные в JMockit, такие как поддержка насмешек равно и хэш-код, переопределен методы, и другие, в настоящее время не поддерживается в PowerMock. Кроме того, есть не эквивалентно возможности JMockit, чтобы захват экземпляров и макет реализации указанной базы типы по мере выполнения теста, без сам тестовый код имеет любой знание фактической реализации занятия.
  • PowerMock использует пользовательские загрузчики классов (обычно по одному на тестовый класс) для того, чтобы создать модифицированные версии из насмешливых классов. Такое тяжелое использование пользовательских загрузчиков класса может привести к конфликты со сторонними библиотеками, следовательно, нужно иногда использовать @PowerMockIgnore ("package.to.be. ignored") аннотация по тестовым классам.
  • механизм, используемый JMockit (runtime instrumentation through a "Java agent") проще и безопаснее, несмотря на то это требует прохождения параметр" - javaagent " для JVM, когда разработка на JDK 1.5; на JDK 1.6+ (который всегда можно использовать для разработка, даже если развертывание на более старая версия) такого нет требование, так как JMockit может прозрачно загрузите агент Java спрос с помощью API присоединения.

еще один недавний насмешливый инструмент Mockito. Хотя и не пытается преодолеть ограничения более старых инструменты (jMock, EasyMock), он делает ввести новый стиль поведения тестирование с насмешками. JMockit также поддерживает этот альтернативный стиль, через API проверок.

JMockit vs Mockito

  • Mockito опирается на явные призывы к его API для того, чтобы отделить код между записью (когда(...)) и проверить (verify(...)) фазы. Этот означает, что любое обращение к макету объект в тестовом коде также потребует вызов насмешливый API-интерфейс. Кроме того, это часто приводит к повторения(...) и проверить(макет)... звонки.
  • С JMockit подобных вызовов не существует. Конечно, у нас есть новый NonStrictExpectations () и new Проверки () вызовы конструктора, но они происходят только один раз за тест (как правило), и полностью отдельно от призывов к издевались над методами и конструкторами.
  • API Mockito содержит несколько несоответствий в синтаксисе, используемом для призывы к издевательским методам. В запишите участок, мы есть такие звонки, как когда (издеваются.mockedMethod (args))... в то время как в фазе проверки этот же вызов будет написано как проверить(макет).mockedMethod (args). Обратите внимание, что в первом случае сделан вызов к mockedMethod непосредственно на макет объекта, в то время как в второй случай сделан на своем объект, возвращаемый verify (mock).
  • JMockit не имеет таких несоответствий, потому что вызовы издевались методы всегда сделаны непосредственно на издевавшихся экземплярах сами себя. (Только с одним исключением: чтобы соответствовать вызовам на одном и том же издевались экземпляр, onInstance(макет) вызов используется, в результате чего код, как onInstance(макет).mockedMethod(args); большинство тестов не нужно будет использовать это, хотя.)
  • как и другие насмешливые инструменты, которые полагаются на метод цепочка / упаковка, Mockito также работает в алогичного синтаксиса, когда раскорчевка пустые методы. Например, вы пишете когда (mockedList.get(1)).thenThrow(новый RuntimeException ()); для Non-void метод, и doThrow(новый RuntimeException ()).когда(mockedList).четкий(); для пустого человека. С JMockit, это всегда один и тот же синтаксис: mockedList.clear (); result = new RuntimeException ();.
  • еще одна непоследовательность возникает в использовании Mockito шпионов: "издевается" что позволяет реальным методам быть выполняется на шпионском экземпляре. Для например, если spy ссылается на пустой Список, то вместо того, чтобы писать когда(шпион.get (0)).затем вернитесь ("foo") вы нужно будет написать доретурн ("фу").когда(шпион).получить(0). С JMockit, динамическая насмешливая функция обеспечивает подобную функциональность к шпионы, но без этого вопроса с тех пор реальные методы выполняются только во время фаза повтора.
  • в EasyMock и jMock, первые насмешливые API для Java, основное внимание было полностью на записи ожидаемого вызовы издевательских методов, для макет объектов, которые (по умолчанию) не разрешить неожиданные вызовы. Те API также обеспечивают запись разрешенные вызовы для макетных объектов это позволяет неожиданные вызовы, но к этому относились как ко второму классу особенность. Кроме того, с этими инструменты нет способа явно проверьте вызовы для издевательств после тестируемый код выполняется. Все такие проверки выполняются неявно и автоматически.
  • в Mockito (а также в Unitils Mock) противоположная точка зрения взятый. Все вызовы для макета объектов это может произойти во время теста, стоит ли записываться или нет, разрешено, не ожидать. Проверка выполняется явно после кода под тестом осуществляется, никогда автоматически.
  • оба подхода слишком экстремальны и, следовательно, менее оптимальны. Jmockit Ожидания И Проверки единственный API, который позволяет разработчик легко выбрать лучшее сочетание строгих (ожидается по умолчанию) и нестрогий (допускается по умолчанию) макетные вызовы для каждого тест.
  • чтобы быть более ясным, API Mockito имеет следующий недостаток. Если вы необходимо проверить, что вызов a непустотный издевательский метод произошел во время тест, но тест требует возвращаемое значение из этого метода, который отличается от значения по умолчанию для возвращаемый тип, затем тест Mockito придется дублировать код: когда (издеваются.someMethod ()).thenReturn(xyz) вызов на этапе записи и a проверить(макет).someMethod () в проверьте фазу. С JMockit, строгий ожидание всегда можно записать, не обязательно быть четко верифицированный. В качестве альтернативы, вызов ограничение количества (раз = 1) может быть указывается для любых записанных нестрогих ожидание (с Мокито такое ограничения могут быть заданы только в проверка (макет, ограничение) вызова).
  • Mockito имеет плохой синтаксис для проверки, в порядке, и для полного проверки (то есть проверка того, что все вызовы для макетных объектов являются явно проверено). В первый случае дополнительный объект должен быть создано, и вызовы для проверки сделаны на это: InOrder inOrder = inOrder(mock1, mock2, ...). Во втором случае звонит как verifyNoMoreInteractions (макет) или verifyZeroInteractions(mock1, mock2) это нужно сделать.
  • С помощью JMockit вы просто пишете new VerificationsInOrder () или new FullVerifications () вместо new Проверки () (или новые FullVerificationsInOrder () для объединения оба требования.) Нет необходимости уточнять который задействованы макетные объекты. Нет дополнительные насмешливые вызовы API. И как бонус, позвонив по телефонам непроверенные инвокации () внутри заказав блок проверки, вы можете выполнение проверок, связанных с заказом в Мокито это просто невозможно.

наконец, инструментарий тестирования JMockit имеет широкий охват и более амбициозные голы чем другие издевательские наборы инструментов, в чтобы обеспечить полное и сложное тестирование разработчиков решение. Хороший API для насмешек, даже без искусственных ограничений, нет достаточно для продуктивного создания тесты. IDE-агностик, прост в использовании, и хорошо интегрированный инструмент покрытия кода также важно, что Покрытие JMockit стремится обеспечить. Еще одна часть тестирования разработчика набор инструментов, который станет более полезным по мере того как набор тестов растет в размере возможность пошагового повторного запуска тестов после локализованного изменения в производство код; это также входит в состав Инструмент покрытия.

(конечно, источник может быть предвзятым, но хорошо...)

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

мой опыт работы с JMockit был очень положительным.

Я работал как с Mockito, так и с JMockit, и мой опыт работы с ними:

  • Mockito:

    • неявное издевательство (- >лучшее удобство использования, но есть опасность не обнаружить запрещенные вызовы метода на издевательствах)
    • явные проверки
  • EasyMock:

    • explict насмехаясь
    • неявное проверка
  • JMockit:

    • поддерживает
  • кроме того, другие преимущества JMockit:

    • Если вы издеваетесь над статическими методами / конструкторами и т. д. (Например, расширение очень старой базы устаревшего кода без UT), у вас будет два варианта: 1) Mockito/EasyMock с расширением Powermock или 2) Jmockit
    • встроенный в отчет о покрытии

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

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

меня качнуло в этой статье

после (по общему признанию большой) кривой обучения, jMockit теперь мой основной модуль тестирования фреймворк для издевается.

для легкого тестирования нашей устаревшей кодовой базы (с большим количеством вызовов статических методов и т. д.), JMockit был неоценим. [Бесстыдный штекер для статьи в своем блоге]

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