Jakie są najlepsze ramy do tworzenia fałszywych obiektów w Javie? Dlaczego? Jakie są zalety i wady poszczególnych ram?
Jakie są najlepsze ramy do tworzenia fałszywych obiektów w Javie? Dlaczego? Jakie są zalety i wady poszczególnych ram?
Odpowiedzi:
Korzystam z Mockito .
Kiedy próbowałem dowiedzieć się o JMock i EasyMock, zauważyłem, że krzywa uczenia się jest nieco stroma (choć może to tylko ja).
Lubię Mockito ze względu na jego prostą i czystą składnię, którą byłem w stanie dość szybko zrozumieć. Minimalna składnia została zaprojektowana tak, aby bardzo dobrze obsługiwać typowe przypadki, chociaż kilka razy, gdy musiałem zrobić coś bardziej skomplikowanego, znalazłem to, co chciałem, było obsługiwane i łatwe do zrozumienia.
Oto (skrócony) przykład ze strony głównej Mockito:
import static org.mockito.Mockito.*;
List mockedList = mock(List.class);
mockedList.clear();
verify(mockedList).clear();
Nie ma nic prostszego.
Jedynym poważnym minusem, jaki mogę wymyślić, jest to, że nie będzie on kpił z metod statycznych.
Jestem twórcą PowerMock, więc oczywiście muszę to polecić! :-)
PowerMock rozszerza zarówno EasyMock, jak i Mockito o możliwość kpienia z metod statycznych , ostatecznych, a nawet prywatnych. Obsługa EasyMock jest kompletna, ale wtyczka Mockito wymaga nieco więcej pracy. Planujemy również dodać obsługę JMock.
PowerMock nie jest przeznaczony do zastępowania innych frameworków, raczej może być użyty w trudnych sytuacjach, gdy inne framework'y nie pozwalają na kpiny. PowerMock zawiera również inne przydatne funkcje, takie jak tłumienie statycznych inicjatorów i konstruktorów.
Witryna projektu JMockit zawiera wiele informacji porównawczych dla aktualnych zestawów narzędzi do kpin.
W szczególności sprawdź macierz porównania funkcji , która obejmuje EasyMock, jMock, Mockito, Unitils Mock, PowerMock i oczywiście JMockit. Staram się, aby był on dokładny i aktualny, o ile to możliwe.
Jest całkiem nowy, więc jest trochę surowy i niedokumentowany. Używa ASM, aby dynamicznie przedefiniować kod bajtowy klasy, dzięki czemu może wyśmiewać wszystkie metody, w tym statyczne, prywatne, konstruktory i statyczne inicjalizatory. Na przykład:
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...
}
Posiada interfejs Oczekiwania, który umożliwia także scenariusze nagrywania / odtwarzania:
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";
}
}
}
}
Minusem jest to, że wymaga Java 5/6.
Możesz także rzucić okiem na testowanie przy użyciu Groovy. W Groovy możesz łatwo wyśmiewać interfejsy Java za pomocą operatora „as”:
def request = [isUserInRole: { roleName -> roleName == "testRole"}] as HttpServletRequest
Oprócz tej podstawowej funkcjonalności Groovy oferuje o wiele więcej na szyderczym froncie, w tym potężne MockFor
i StubFor
klasy.
Zacząłem używać mocków w EasyMock . Łatwo to zrozumieć, ale powtórka była dość irytująca. Mockito usuwa to, ma również czystszą składnię, ponieważ wygląda na to, że czytelność była jednym z jej głównych celów. Nie mogę wystarczająco podkreślić, jak ważne jest to, ponieważ większość programistów poświęci swój czas na czytanie i utrzymanie istniejącego kodu, a nie jego tworzenie.
Kolejną miłą rzeczą jest to, że interfejsy i klasy implementacyjne są obsługiwane w ten sam sposób, w przeciwieństwie do EasyMock, w którym nadal trzeba pamiętać (i sprawdzać), aby użyć rozszerzenia klasy EasyMock.
Niedawno rzuciłem okiem na JMockit i chociaż lista funkcji prania jest dość wyczerpująca, myślę, że ceną tego jest czytelność wynikowego kodu i konieczność pisania więcej.
Dla mnie Mockito trafia w dobry punkt, jest łatwy do pisania i czytania oraz radzenia sobie z większością sytuacji, w których wymagany będzie większość kodu. Używanie Mockito z PowerMock byłoby moim wyborem.
Jedną rzeczą do rozważenia jest to, że narzędzie, które wybierzesz, jeśli tworzysz sam lub w małym zgranym zespole, może nie być najlepszym rozwiązaniem dla dużej firmy z programistami o różnych poziomach umiejętności. Czytelność, łatwość użycia i prostota wymagałyby więcej uwagi w tym drugim przypadku. Nie ma sensu uzyskiwać ostatecznego frameworka, jeśli wiele osób ostatecznie go nie używa lub nie utrzymuje testów.
W pracy intensywnie korzystamy z EasyMock i EasyMock Class Extension i jesteśmy z tego bardzo zadowoleni. Zasadniczo daje wszystko, czego potrzebujesz. Spójrz na dokumentację, jest bardzo ładny przykład, który pokazuje wszystkie funkcje EasyMock.
Użyłem JMock wcześnie. Próbowałem Mockito przy moim ostatnim projekcie i podobało mi się. Bardziej zwięzłe, bardziej czyste. PowerMock obejmuje wszystkie potrzeby, których nie ma w Mockito, takie jak wyśmiewanie kodu statycznego, wyśmiewanie tworzenia instancji, wyśmiewanie końcowych klas i metod. Mam więc wszystko, czego potrzebuję do wykonania mojej pracy.
Lubię JMock, ponieważ jesteś w stanie ustawić oczekiwania. Jest to całkowicie odmienne od sprawdzania, czy w niektórych fałszywych bibliotekach została wywołana metoda. Za pomocą JMock możesz pisać bardzo wyszukane oczekiwania. Zobacz jmock cheat-sheat .
Tak, Mockito to świetny framework. Używam go razem z hamcrestem i guice Google do konfiguracji moich testów.
Najlepszym rozwiązaniem drwiny jest zlecenie, aby maszyna wykonała całą pracę dzięki zautomatyzowanym testom opartym na specyfikacji. Jeśli chodzi o Javę, zobacz ScalaCheck i środowisko Reductio zawarte w bibliotece Functional Java . Dzięki zautomatyzowanym ramom testowym opartym na specyfikacji dostarczasz specyfikację testowanej metody (właściwość, która powinna być prawdziwa), a struktura automatycznie generuje testy, a także próbne obiekty.
Na przykład następująca właściwość testuje metodę Math.sqrt, aby sprawdzić, czy pierwiastek kwadratowy z dowolnej liczby dodatniej n kwadrat jest równy n.
val propSqrt = forAll { (n: Int) => (n >= 0) ==> scala.Math.sqrt(n*n) == n }
Kiedy dzwonisz propSqrt.check()
, ScalaCheck generuje setki liczb całkowitych i sprawdza twoją własność dla każdej z nich, automatycznie również upewniając się, że skrzynki brzegowe są dobrze pokryte.
Mimo że ScalaCheck jest napisany w języku Scala i wymaga kompilatora Scala, łatwo jest z nim przetestować kod Java. Struktura Reductio w Functional Java to czysta implementacja Java tych samych pojęć.
Mockito zapewnia również opcję stubowania, dopasowywania argumentów (jak anyInt () i anyString ()), sprawdzania liczby wywołań (times (3), atLeastOnce (), never ()) i innych .
Przekonałem się również, że Mockito jest prosty i czysty .
Jedną rzeczą, która mi się nie podoba w Mockito, jest to, że nie można upuścić metod statycznych .
Zacząłem używać mocków za pomocą JMocka, ale ostatecznie przeszedłem na EasyMock. EasyMock był po prostu tym - łatwiejszy - i zapewniał bardziej naturalną składnię. Od tamtej pory nie zmieniłem się.