Сравнение Mockito и JMockit - почему за Mockito проголосовали лучше, чем за JMockit?

Я изучаю, какой фреймворк для фиксации использовать в моем проекте, и сузил его до JMockit и Mockito.

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

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


person Community    schedule 05.11.2010    source источник
comment
возможно, лучшее удобство использования для mockito, кстати, я не думаю, что JMockit более зрелый, чем Mockito ...   -  person Alois Cochard    schedule 05.11.2010
comment
Судя по количеству голосов, ОЗНАКО, что ответы на этот вопрос очень востребованы сообществом. Это означает, что стратегия ортогонализации этого сайта, которая привела к закрытию этого вопроса, требует серьезного переосмысления - в том смысле, что этот сайт часто наступал на ногу, чтобы дать необходимые ответы, упав на свою несовпадающую ортогональность. Не осознавая, что в граф-анализе дерева существует столько способов увидеть ортогональность дерева, сколько узлов. Возможно, ортогональность этого сайта, а не вопрос, неверна.   -  person Blessed Geek    schedule 07.11.2013
comment
+1 за то, что не закрыл. Эти ответы имеют огромную ценность. Выбрать технологию непросто, и ответы на эти вопросы помогут сэкономить много времени. На самом деле правильного ответа может и не быть, но StackOverflow должен отвечать на вопросы без ответа.   -  person mhstnsc    schedule 21.01.2016
comment
Я добавлю свою поддержку тем, кто заявляет, что закрывать это как неконструктивное - нелепо. Приведенные здесь ответы были подтверждены фактами, ссылками и / или опытом. Вопрос в области технологий, который не вызывает дебатов, опросов или расширенных обсуждений, обычно не стоит задавать. Кроме того, предоставление фактов и экспертных знаний основывается на разном опыте, и эти различия приведут к дебатам и расширенным обсуждениям.   -  person Jeff Nyman    schedule 30.05.2016
comment
@Alois - вы можете привести конкретные примеры, когда JMockit выглядит менее зрелым, чем Mockito?   -  person NitinS    schedule 11.12.2016


Ответы (5)


Обновление, сентябрь 2019 г .: единственный фреймворк mocking, поддерживаемый (по умолчанию) Spring Boot, это Mockito < / сильный>. Если вы используете Spring, ответ очевиден.


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

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

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

Что касается прокси и CGLIB по сравнению с инструментарием:

(EasyMock и jMock) основаны на java.lang.reflect.Proxy, который требует реализации интерфейса. Кроме того, они поддерживают создание фиктивных объектов для классов посредством генерации подклассов 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 (Expectations) похож как на EasyMock, так и на jMock. Хотя это создает более длительную кривую обучения, это также позволяет JMockit предоставлять более простой, согласованный и легкий в использовании API.
  • По сравнению с JMockit Expectations API, PowerMock API является более «низкоуровневым», заставляя пользователей выяснять и указывать, какие классы необходимо подготовить для тестирования (с аннотацией @PrepareForTest ({ClassA.class, ...}) ) и требуя определенных вызовов API для работы с различными типами языковых конструкций, которые могут присутствовать в производственном коде: статические методы (mockStatic (ClassA.class)), конструкторы (подавить (constructor (ClassXyz.class))), вызовы конструкторов ( expectNew (AClass.class)), частичные имитации (createPartialMock (ClassX.class, «methodToMock»)) и т. д.
  • С JMockit Expectations все виды методов и конструкторов имитируются чисто декларативным способом, с частичным имитированием, указанным с помощью регулярных выражений в аннотации @Mocked, или просто «демокингом» членов без записанных ожиданий; то есть разработчик просто объявляет некоторые общие «фиктивные поля» для тестового класса или некоторые «локальные фиктивные поля» и / или «фиктивные параметры» для отдельных методов тестирования (и в этом последнем случае аннотация @Mocked часто не быть нужным).
  • Некоторые возможности, доступные в JMockit, такие как поддержка имитации равенства и hashCode, переопределенных методов и другие, в настоящее время не поддерживаются в PowerMock. Кроме того, нет эквивалента способности JMockit захватывать экземпляры и имитировать реализации указанных базовых типов во время выполнения теста, если сам тестовый код не знает реальных классов реализации.
  • PowerMock использует пользовательские загрузчики классов (обычно по одному на тестовый класс) для создания модифицированных версий имитируемых классов. Такое интенсивное использование пользовательских загрузчиков классов может привести к конфликтам со сторонними библиотеками, поэтому иногда возникает необходимость использовать аннотацию @PowerMockIgnore («package.to.be.ignored») в тестовых классах.
  • Механизм, используемый JMockit (инструментарий времени выполнения с помощью «Java-агента»), проще и безопаснее, хотя он требует передачи параметра «-javaagent» в JVM при разработке на JDK 1.5; в JDK 1.6+ (который всегда можно использовать для разработки, даже если выполняется развертывание в более старой версии) такого требования нет, поскольку JMockit может прозрачно загружать агент Java по запросу с помощью Attach API.

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

JMockit против Mockito

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

Наконец, JMockit Testing Toolkit имеет более широкую область применения и более амбициозные цели, чем другие наборы инструментов для фиксации, чтобы предоставить полное и сложное решение для тестирования разработчиков. Хорошего API для mocking'а, даже без искусственных ограничений, недостаточно для продуктивного создания тестов. Независимый от IDE, простой в использовании и хорошо интегрированный инструмент Code Coverage также важен, и именно это JMockit Coverage стремится обеспечить. Еще одна часть набора инструментов для тестирования разработчика, которая станет более полезной по мере увеличения размера набора тестов, - это возможность постепенно повторно запускать тесты после локализованного изменения производственного кода; это также включено в инструмент покрытия.

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

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

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

person Hendy Irawan    schedule 22.06.2011
comment
Я никогда не использовал jmockit, но хотел бы добавить еще один аргумент в обсуждение: взгляните на сравнение тенденций Google всех обсуждаемых фреймворков. По состоянию на 06.06.2012 JMockit даже не отображается на графике тенденций Google по сравнению с Mockito и EasyMock. И количество пользователей также важно при выборе фреймворка. - person machinery; 06.06.2012
comment
Это довольно странно. Mockito и JMockIt дают мне 409 'и 83' попаданий в Google соответственно. Конечно, JMockIt должен хотя бы появиться. - person thoredge; 29.08.2012
comment
Ваш ответ очень полезен. Я планировал просто использовать Mockito, но сейчас я сначала протестирую JMockit. Звучит неплохо, чтобы не пробовать. @machinery: Да, важно смотреть на тенденции, но выбор его в качестве основного критерия ограничит вас основным потоком и защитит вас от инноваций. - person deamon; 07.05.2013
comment
Я знаю, что это старая ветка, но после прочтения этого обзора я подумал, что тоже попробую. Я должен сказать, что на первый взгляд JMockit очень многообещающий. Однако на сегодняшний день я обнаружил, что поддержка этого сообщества очень недостаточна. У меня возникла большая проблема с моим пониманием Mock API, и после публикации моих проблем я не получил ответа в течение 2 дней. - person Eric B.; 30.09.2015
comment
Я использовал комбинацию (Mockito и PowerMock) и JMockIt; я был очень впечатлен JMockIt - person Venkatesh Laguduva; 05.04.2017
comment
@EricB. Эрик, что ты имеешь в виду, что ты не получил ответа после публикации проблем в системе отслеживания проблем JMockit?!? Я ответил на все ваши вопросы в тот же день, когда они были опубликованы: github.com/jmockit/jmockit1/ - person Rogério; 26.06.2017
comment
@rogerio. В самом деле, вы это сделали. Это был комментарий двухлетней давности, поэтому я не могу точно вспомнить ситуацию, но вы определенно смогли ответить на все вопросы. Однако самая большая проблема заключается в том, что в основном вы предоставляете все ответы, что является позором для такой великолепной структуры. Было бы так здорово, если бы были другие люди, которые могли бы ответить и поделиться своими мыслями так же хорошо, как и вы. Это также означает, что ответы ограничены вашей личной пропускной способностью, которая, по понятным причинам, имеет свои ограничения. - person Eric B.; 26.06.2017
comment
@Handy Irawan Строка о том, что JMockit не требует JavaAgent для нового JDK, не совсем верна. - person S.D.; 19.02.2019
comment
Ответу 8 лет, поэтому многие вещи в ответе неверны. Один момент заключается в том, что JMockit требует флаг -javaagent с 1.42, потому что вы больше не можете самостоятельно подключаться, поскольку Java 9, и поиск подходящих обходных путей, очевидно, не входил в компетенцию разработчика. Другой момент заключается в том, что JMockit больше не позволяет имитировать частные методы и конструкторы, в то время как PowerMock делает afaik. - person Vampire; 11.09.2019

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

  • Мокито:

    • implicit mocking (-> better usability, but has the danger of failing to detect not-allowed method calls on mocks)
    • явная проверка
  • EasyMock:

    • explict mocking
    • неявная проверка
  • JMockit:

    • supports both
  • Кроме того, другие преимущества JMockit:

    • if you're mocking static methods/constructors etc (such as extending a very old legacy code base without UT), you'll have two choices: 1) Mockito/EasyMock with Powermock extension or 2) Jmockit
    • встроенный отчет о покрытии

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

person Tumer    schedule 29.09.2011
comment
есть stackoverflow.com/questions/8003278/ verifyNoMoreInteractions Я полагаю, если вы хотите псевдо явное издевательство с mockito - person rogerdpack; 01.01.2014
comment
@Hendy Irawan, не могли бы вы помочь stackoverflow.com / questions / 63590630 / - person spandey; 26.08.2020
comment
@Dave Moten, не могли бы вы помочь stackoverflow.com / questions / 63590630 / - person spandey; 26.08.2020

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

Меня впечатлила эта статья

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

person Joseph Erickson    schedule 24.01.2011
comment
Возможно, если вы чувствуете, что вам нужно протестировать частные методы, вас слишком беспокоит то, как работает ваш код, а не то, что он делает (что является реальным моментом, и что можно определить, используя только его общедоступные методы). Также мне было бы интересно прочитать эту статью, но ссылка не работает. - person codebox; 22.08.2013
comment
Спустя 4 года вы все еще используете jMockit в качестве основной среды тестирования? Я пробую его впервые и сталкиваюсь с некоторыми проблемами, но не знаю, неправильно ли я понимаю, как работает jMockit, или это функция, которой просто не существует. - person Eric B.; 30.09.2015
comment
jMockit больше не поддерживает тестирование частных методов. Класс Deencapsulation постепенно устарел, а затем был полностью удален в версии 1.47. jmockit.github.io/changes.html - person Pytry; 17.04.2020
comment
@ Джозеф Эриксон, не могли бы вы проверить stackoverflow.com / questions / 63590630 / - person spandey; 26.08.2020

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

person Jeff Olson    schedule 30.11.2010
comment
Можете ли вы проверить stackoverflow.com/questions/ 63590630 / - person spandey; 26.08.2020

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

person Bivas    schedule 05.11.2010