Оновлення вересня 2019 року: Єдиний глузливий фреймворк, який підтримує (за замовчуванням) 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. Через це згадані класи не можуть бути остаточними, і з них можна знущатись лише з методів, що перезаписуються. Найголовніше, однак, при використанні цих інструментів залежність коду, що перевіряється (тобто об'єкти інших класів, від яких залежить даний клас, який перевіряється), повинні контролюватися тестами, щоб макетні екземпляри могли передаватися клієнтам цих залежностей. Отже, залежності не можна просто встановити з новим оператором у класі клієнта, для якого ми хочемо написати тести одиниць.
Зрештою, технічні обмеження звичайних знущальних інструментів накладають такі дизайнерські обмеження на виробничий код:
- Кожен клас, який, можливо, потребує знущання в тесті, повинен або реалізувати окремий інтерфейс, або не бути остаточним.
- Залежності кожного класу, що підлягає тестуванню, повинні бути або отримані за допомогою налаштованих методів створення екземплярів (фабрики або локатор обслуговування), або піддаватися впливу ін'єкцій залежностей. В іншому випадку одиничні тести не зможуть передати макетні реалізації залежностей тестовому блоку.
- Оскільки тільки з методів екземплярів можна знущатися, класи, які піддаються тестуванню, не можуть викликати статичні методи залежно від їх залежностей, а також інстанціювати їх за допомогою будь-якого конструктора.
Зазначене скопійовано з http://jmockit.org/about.html . Крім того, він порівнює між собою (JMockit), PowerMock та Mockito кількома способами:
Зараз для Java є інші інструменти знущань, які також долають обмеження звичайних, між ними PowerMock, jEasyTest та MockInject. Найближчий до набору функцій JMockit - це PowerMock, тому я коротко його оціню тут (до того ж, інші два є більш обмеженими і, здається, вже не активно розвиваються).
JMockit проти PowerMock
- Перш за все, PowerMock не забезпечує повний API для глузування, але натомість працює як розширення до іншого інструменту, який на даний момент може бути EasyMock або Mockito. Це, очевидно, перевага для існуючих користувачів цих інструментів.
- З іншого боку, JMockit пропонує абсолютно нові API, хоча його основний API (очікування) схожий як на EasyMock, так і на jMock. Хоча це створює більш довгу криву навчання, вона також дозволяє JMockit надати більш простий, більш послідовний та простий у використанні API.
- Порівняно з API очікувань JMockit API PowerMock є більш "низьким рівнем", що змушує користувачів розібратися та вказати, які класи потрібно підготувати до тестування (з анотацією @PrepareForTest ({ClassA.class, ...}) ) і вимагає конкретних викликів API для роботи з різними типами мовних конструкцій, які можуть бути присутніми у виробничому коді: статичні методи (mockStatic (ClassA.class)), конструктори (suppress (конструктор (ClassXyz.class))),) виклики конструктора ( очікуємоNew (AClass.class)), часткові макети (createPartialMock (ClassX.class, "methodToMock")) тощо
- З очікуваннями JMockit всі види методів та конструкторів висміюються чисто декларативно, з частковим глузуванням, визначеним регулярними виразами в анотації @Mocked, або просто "відмежуванням" членів без зафіксованих очікувань; тобто розробник просто оголошує деякі спільні "макетні поля" для тестового класу, або якісь "локальні макетні поля" та / або "параметри макету" для окремих методів тестування (і в цьому останньому випадку анотація @Mocked часто не буде потрібні).
- Деякі можливості, доступні в JMockit, такі як підтримка макетування рівних та хеш-кодів, перекритих методів та інших, наразі не підтримуються в PowerMock. Крім того, немає еквіваленту здатності JMockit захоплювати екземпляри та знущатися над реалізацією вказаних базових типів під час виконання тесту, без того, щоб сам тестовий код не мав ніяких знань про фактичні класи реалізації.
- PowerMock використовує завантажувачі спеціального класу (як правило, по одному на тестовий клас), щоб генерувати модифіковані версії макетних класів. Настільки велике використання навантажувачів спеціальних класів може призвести до конфліктів із сторонніми бібліотеками, отже, потреба іноді використовувати тест @PowerMockIgnore ("package.to.be.ignored") на тестових класах.
- Механізм, який використовується JMockit (інструментарій виконання через «агент Java»), простіший і безпечніший, хоча для розробки на JDK 1.5 потрібен передача параметра «-javaagent» JVM; в JDK 1.6+ (який завжди можна використовувати для розробки, навіть якщо розгортання на більш старій версії) немає такої вимоги, оскільки JMockit може прозоро завантажувати Java-агент на вимогу за допомогою API Attach.
Ще один останній інструмент глузування - Mockito. Хоча він не намагається подолати обмеження старих інструментів (jMock, EasyMock), він вводить новий стиль тестування поведінки з макетами. JMockit також підтримує цей альтернативний стиль через API підтвердження.
JMockit проти Mockito
- Mockito покладається на явні виклики до свого API, щоб розділити код між записами (коли (...)) та перевірити (перевірити (...)) фази. Це означає, що будь-яке виклик до макетного об’єкта в тестовому коді також вимагатиме виклику до глузливого API. Крім того, це часто призводить до повторних викликів під час (...) та перевірки (знущань) ... дзвінків.
- З JMockit подібних дзвінків не існує. Звичайно, у нас є нові виклики конструктора NonStrictExpe очікувань () та нові верифікації (), але вони трапляються лише один раз за тест (як правило) і повністю відокремлюються від викликів до знущаються методів та конструкторів.
- API Mockito містить декілька невідповідностей у синтаксисі, який використовується для викликів методів глузування. На фазі запису у нас є виклики, як коли (mock.mockedMethod (args)) ... в той час як на фазі верифікації цей же виклик буде записаний як verify (mock) .mockedMethod (args). Зауважте, що в першому випадку виклик mockedMethod робиться безпосередньо на макетному об'єкті, тоді як у другому випадку він робиться на об'єкті, поверненому верифікацією (макетом).
- У JMockit немає таких невідповідностей, оскільки виклики до методів глузування завжди робляться безпосередньо на самих знущаються екземплярах. (За винятком лише одного вибору: для відповідності викликам у тому ж знуреному екземплярі використовується виклик onInstance (mock), що призводить до такого коду, як onInstance (mock) .mockedMethod (args); хоча більшість тестів не потрібно використовувати це. )
- Як і інші глузуючі інструменти, які покладаються на прив'язування / обгортання методів, Mockito також стикається з непослідовним синтаксисом під час заглушення методів недійсності. Наприклад, ви пишете, коли (mockedList.get (1))., ПотімThrow (новий RuntimeException ()); для недійсного методу і doThrow (новий RuntimeException ())., коли (mockedList) .clear (); за нікчемну. З JMockit це завжди той самий синтаксис: mockedList.clear (); результат = новий RuntimeException () ;.
- Ще одна невідповідність виникає у використанні шпигунів Mockito: "макети", які дозволяють виконувати реальні методи на шпигунському екземплярі. Наприклад, якщо шпигун посилається на порожній Список, то замість того, щоб писати коли (spy.get (0)). Тоді повернути ("foo"), вам потрібно буде написати doReturn ("foo"). 0). З JMockit функція динамічного глузування забезпечує аналогічні функції шпигунів, але без цього питання, оскільки реальні методи виконуються лише на етапі повторного відтворення.
- У EasyMock та jMock, перших API для глузування для Java, увага зосереджувалася повністю на записі очікуваних викликів знущаються методів, для об'єктів знущань, які (за замовчуванням) не дозволяють несподіваних викликів. Ці API також забезпечують запис дозволених викликів для макетних об'єктів, які дозволяють несподівано викликати, але це трактується як особливість другого класу. Крім того, за допомогою цих інструментів немає можливості явно перевірити виклики для макетів після використання тестового коду. Всі такі перевірки проводяться неявно та автоматично.
- У Mockito (а також в Unitils Mock) приймається протилежна точка зору. Усі виклики для знущань над об'єктами, які можуть статися під час тесту, записані чи ні, дозволені, ніколи не очікувані. Перевірка проводиться явно після виконання тестового коду, ніколи автоматично.
- Обидва підходи є надто екстремальними, а отже, менш оптимальними. Очікування та перевірки JMockit - єдиний API, який дозволяє розробникові безперешкодно вибирати найкращу комбінацію строгих (очікуваних за замовчуванням) та нестрогих (дозволених за замовчуванням) макетів викликів для кожного тесту.
- Щоб бути більш зрозумілим, API Mockito має такий недолік. Якщо вам потрібно переконатися, що виклик до недійсного методу знущань стався під час тесту, але для тесту потрібно повернути значення цього методу, яке відрізняється від типового для типу повернення, тоді тест Mockito матиме повторюваний код: a, коли (mock.someMethod ()). тоді повертається (xyz) у фазі запису, а у фазі перевірки - verif (макет) .someMethod (). З JMockit завжди можна записати суворе очікування, яке не доведеться чітко перевіряти. Альтернативно, обмеження кількості викликів (разів = 1) може бути визначене для будь-яких записаних не суворих очікувань (при Mockito такі обмеження можуть бути вказані лише у виклику підтвердження (макет, обмеження)).
- У Mockito є поганий синтаксис як для перевірки в порядку, так і для повної перевірки (тобто перевірки, що всі виклики для макетування об'єктів явно перевірені). У першому випадку потрібно створити додатковий об’єкт і викликати перевірку зроблених на ньому: InOrder inOrder = inOrder (mock1, mock2, ...). У другому випадку потрібно робити дзвінки, такі як verifyNoMoreInteractions (макет) або verifyZeroInteractions (mock1, mock2).
- За допомогою JMockit ви просто пишете нову VerificationInOrder () або нову FullVerifications () замість нових Verification () (або новий FullVerificationsInOrder (), щоб поєднати обидві вимоги). Не потрібно вказувати, які макетні об’єкти задіяні. Немає зайвих глузуючих дзвінків API. І як бонус, зателефонувавши unverifiedInvocations () всередині впорядкованого блоку підтвердження, ви можете виконати перевірки, пов’язані з замовленнями, які просто неможливі в Mockito.
Нарешті, інструментарій тестування інструментів JMockit має ширший обсяг та амбітніші цілі, ніж інші глузливі набори інструментів, щоб забезпечити повноцінне та складне рішення для тестування розробників. Хорошого API для глузування, навіть без штучних обмежень, недостатньо для продуктивного створення тестів. IDE-агностик, простий у використанні та добре інтегрований інструмент покриття коду також є важливим, і саме це має на меті запропонувати JMockit Coverage. Ще один фрагмент набору інструментів для тестування розробників, який стане більш корисним у міру збільшення розміру тестового набору - це можливість поступового повторного повторного тестування після локальної зміни виробничого коду; це також включено в інструмент Покриття.
(надано, джерело може бути упередженим, але добре ...)
Я б сказав, що йдіть з JMockit . Це найпростіший у використанні, гнучкий, і працює у майже всіх випадках, навіть у складних ситуаціях та сценаріях, коли ви не можете керувати тестуваним класом (або ви не можете його зламати через причини сумісності тощо).
Мій досвід роботи з JMockit був дуже позитивним.