Яка найкраща основа для створення макетних об’єктів на Java? Чому? Які плюси і мінуси кожної структури?
Яка найкраща основа для створення макетних об’єктів на Java? Чому? Які плюси і мінуси кожної структури?
Відповіді:
Я мав добрий успіх, використовуючи Mockito .
Коли я спробував дізнатися про JMock та EasyMock, я виявив, що крива навчання трохи крута (хоча, можливо, це лише я).
Мені подобається Mockito через його простий і чистий синтаксис, який мені вдалося зрозуміти досить швидко. Мінімальний синтаксис розроблений для того, щоб дуже добре підтримувати поширені випадки, хоча за кілька разів мені потрібно було зробити щось складніше, я знайшов те, що хотів, щоб було підтримано і легко зрозуміти.
Ось (скорочений) приклад із домашньої сторінки Mockito:
import static org.mockito.Mockito.*;
List mockedList = mock(List.class);
mockedList.clear();
verify(mockedList).clear();
Це не стає набагато простішим за це.
Єдиний головний недолік, про який я можу подумати - це те, що він не буде знущатися над статичними методами.
Я творець PowerMock, так очевидно, що я повинен рекомендувати це! :-)
PowerMock розширює як EasyMock, так і Mockito з можливістю знущатися над статичними методами , остаточними та навіть приватними методами. Підтримка EasyMock завершена, але плагіну Mockito потрібно ще трохи працювати. Ми також плануємо додати підтримку JMock.
PowerMock не призначений для заміни інших фреймворків, скоріше він може бути використаний у складних ситуаціях, коли інші рамки не дозволяють глузувати. PowerMock також містить інші корисні функції, такі як придушення статичних ініціалізаторів та конструкторів.
Сайт JMockit проект містить велику кількість порівняльних даних для поточних інструментарії Mocking.
Зокрема, ознайомтеся з матрицею порівняння функцій , яка охоплює EasyMock, jMock, Mockito, Unitils Mock, PowerMock і, звичайно, JMockit. Я намагаюся якомога більше бути точним та актуальним.
Я мав успіх у JMockit .
Це досить нове, а тому трохи сире і недодокументоване. Він використовує ASM для динамічного переосмислення байт-коду класу, тому може знущатися з усіх методів, включаючи статичні, приватні, конструктори та статичні ініціалізатори. Наприклад:
import mockit.Mockit;
...
Mockit.redefineMethods(MyClassWithStaticInit.class,
MyReplacementClass.class);
...
class MyReplacementClass {
public void $init() {...} // replace default constructor
public static void $clinit{...} // replace static initializer
public static void myStatic{...} // replace static method
// etc...
}
Він має інтерфейс очікувань, що дозволяє також записувати / відтворювати сценарії:
import mockit.Expectations;
import org.testng.annotations.Test;
public class ExpecationsTest {
private MyClass obj;
@Test
public void testFoo() {
new Expectations(true) {
MyClass c;
{
obj = c;
invokeReturning(c.getFoo("foo", false), "bas");
}
};
assert "bas".equals(obj.getFoo("foo", false));
Expectations.assertSatisfied();
}
public static class MyClass {
public String getFoo(String str, boolean bool) {
if (bool) {
return "foo";
} else {
return "bar";
}
}
}
}
Мінусом є те, що для цього потрібна Java 5/6.
Ви також можете поглянути на тестування за допомогою Groovy. У Groovy ви можете легко знущатися з інтерфейсів Java, використовуючи оператор "as":
def request = [isUserInRole: { roleName -> roleName == "testRole"}] as HttpServletRequest
Крім основної функціональності, Groovy пропонує ще багато іншого на глузливому фронті, включаючи потужні MockFor
та StubFor
класи.
Я почав використовувати макети з EasyMock . Досить просто зрозуміти, але крок повторення начебто дратував. Mockito усуває це, також має більш чистий синтаксис, оскільки, схоже, читабельність була однією з його головних цілей. Я не можу підкреслити, наскільки це важливо, оскільки більшість розробників витратить свій час на читання та підтримку існуючого коду, не створюючи його.
Ще одна приємна річ - те, що інтерфейси та класи реалізації обробляються однаково, на відміну від EasyMock, де все-таки потрібно запам'ятати (і перевірити), щоб використовувати розширення класу EasyMock.
Нещодавно я швидко оглянув JMockit , і хоча список функцій білизни є досить вичерпним, я думаю, що ціна цього - розбірливість отриманого коду, і потрібно писати більше.
Для мене Mockito потрапляє у приємне місце, тому що його легко писати та читати, а також розбиратись у більшості ситуацій, які потребують більшості кодів. Використання Mockito з PowerMock було б моїм вибором.
Одне, що слід врахувати, - це те, що інструмент, який ви обрали б, якщо ви розробляли самостійно або в невеликій дружній команді, може бути не найкращим для великої компанії з розробниками різного рівня кваліфікації. Читання, простота використання та простота потребують більшого розгляду в останньому випадку. Немає сенсу отримувати кінцевий глузливий фреймворк, якщо багато людей в кінцевому підсумку не використовують його чи не підтримують тести.
Ми активно використовуємо EasyMock і EasyMock Class Extension на роботі і дуже задоволені цим. Це в основному дає вам все необхідне. Погляньте на документацію, є дуже приємний приклад, який показує вам всі функції EasyMock.
Я використовував JMock рано. Я спробував Mockito на своєму останньому проекті і сподобався. Більш лаконічна, чистіша. PowerMock охоплює всі потреби, які відсутні в Mockito, такі як знущання над статичним кодом, глузування зі створення екземпляра, глузування з фінальних класів та методів. Тож у мене є все, що потрібно для виконання своєї роботи.
Мені подобається JMock, тому що ти вмієш налаштувати очікування. Це абсолютно відрізняється від перевірки, чи був викликаний метод, знайдений у деяких макетних бібліотеках. За допомогою JMock ви можете написати дуже складні очікування. Побачити чимак - шит .
Так, Мокіто - це чудова рамка. Я використовую його разом із hamcrest та Google Guice для налаштування моїх тестів.
Найкраще рішення для глузування - дозволити машині виконати всю роботу за допомогою автоматизованого тестування на основі специфікацій. Щодо Java, див. ScalaCheck та рамку Reductio, що входить у функціональну бібліотеку Java . За допомогою автоматизованих фреймворків тестування на основі специфікацій ви надаєте специфікацію досліджуваного методу (властивість щодо нього, яка повинна бути правдою), і фреймворк генерує тести, а також макети об'єктів автоматично.
Наприклад, наступні властивості перевіряють метод Math.sqrt, щоб перевірити, чи дорівнює квадратний корінь будь-якого додатного числа n у квадраті.
val propSqrt = forAll { (n: Int) => (n >= 0) ==> scala.Math.sqrt(n*n) == n }
Під час дзвінка propSqrt.check()
ScalaCheck генерує сотні цілих чисел і перевіряє вашу власність для кожного, а також автоматично переконуючись, що крайові регістри добре покриті.
Навіть незважаючи на те, що ScalaCheck написаний у Scala та вимагає компілятора Scala, перевірити код Java за допомогою нього легко. Рамка Reductio у функціональній Java - це реальна реалізація тих же концепцій Java.
Mockito також надає можливість методів заглушки, відповідності аргументів (як anyInt () та anyString ()), перевірки кількості викликів (разів (3), atLeastOnce (), ніколи ()) та багато іншого .
Я також виявив, що Мокіто простий і чистий .
Одне, що мені не подобається в Mockito, - це те, що ти не можеш перешкодити статичним методам .
Я почав використовувати макети через JMock, але з часом перейшов на використання EasyMock. EasyMock був саме цим, - легше - і надав синтаксис, який відчував себе більш природним. Я з тих пір не перейшов.