Napisałem kilka testów jednostkowych dla metody statycznej. Metoda statyczna przyjmuje tylko jeden argument. Typ argumentu jest klasą końcową. Pod względem kodu:
public class Utility {
public static Optional<String> getName(Customer customer) {
// method's body.
}
}
public final class Customer {
// class definition
}
Tak dla Utility
klasy I stworzyliśmy klasę testową UtilityTests
, w której mam napisane testy na tej metodzie getName
. Środowisko testowania jednostkowego to TestNG, a używana jest fałszywa biblioteka Mockito
. Typowy test ma więc następującą strukturę:
public class UtilityTests {
@Test
public void getNameTest() {
// Arrange
Customer customerMock = Mockito.mock(Customer.class);
Mockito.when(...).thenReturn(...);
// Act
Optional<String> name = Utility.getName(customerMock);
// Assert
Assert.assertTrue(...);
}
}
Jaki jest problem ?
Podczas gdy testy przebiegają pomyślnie lokalnie, wewnątrz IntelliJ, nie działają na Jenkinsie (kiedy pcham mój kod w zdalnej gałęzi, uruchamiana jest kompilacja, a testy jednostkowe uruchamiane na końcu). Komunikat o błędzie jest następujący:
org.mockito.exceptions.base.MockitoException: Nie można wyśmiewać / szpiegować klasy com.packagename. Klient Mockito nie może wyśmiewać / szpiegować, ponieważ: - klasa ostateczna
Co próbowałem
Szukałem trochę, aby znaleźć rozwiązanie, ale nie udało mi się. Zaznaczam tutaj, że nie wolno mi zmieniać faktu, że Customer
jest to klasa ostateczna . Poza tym chciałbym, jeśli to możliwe, w ogóle nie zmieniać jego projektu (np. Stworzyć interfejs, który przechowuje metody, które chcę wyśmiewać i stwierdza, że klasa Customer implementuje ten interfejs, jak słusznie zauważył Jose w swoim komentarz). To, czego próbowałem, to druga opcja wspomniana na finale mockito . Pomimo tego, że rozwiązało to problem, hamuje kilka innych testów jednostkowych :(, których nie można naprawić w żaden widoczny sposób.
pytania
Oto dwa pytania, które mam:
- Jak to w ogóle możliwe? Czy test nie powinien zawieść zarówno lokalnie, jak i w Jenkins?
- Jak można to naprawić w oparciu o ograniczenia, o których wspomniałem powyżej?
Z góry dziękuję za wszelką pomoc.
źródło
enable final
konfiguracja działa w twoim obszarze roboczym, ale po uruchomieniuJenkins
nie można znaleźć tego pliku. Sprawdź, gdzieJenkins
szuka pliku i czy rzeczywiście tam jest, czy nie.Customer
ma w tym jakąś logikę, czy to tylko głupia klasa danych? Jeśli to tylko kilka pól z modułami pobierającymi i ustawiającymi, możesz po prostu utworzyć jego instancję.Odpowiedzi:
Alternatywnym podejściem byłoby użycie wzorca „metoda do klasyfikacji”.
Oto dobry blog na ten temat: https://simpleprogrammer.com/back-to-basics-mock- Eliminating-patterns/
źródło
To oczywiście rodzaj env-specyfiki. Jedyne pytanie brzmi - jak ustalić przyczynę różnicy.
Sugeruję sprawdzenie
org.mockito.internal.util.MockUtil#typeMockabilityOf
metody i porównanie, comockMaker
jest faktycznie używane w obu środowiskach i dlaczego.Jeśli
mockMaker
jest to samo - porównaj załadowane klasyIDE-Client
vsJenkins-Client
- czy mają one jakąkolwiek różnicę w czasie wykonywania testu.Poniższy kod został napisany przy założeniu OpenJDK 12 i Mockito 2.28.2, ale wierzę, że można go dostosować do dowolnej faktycznie używanej wersji.
Z osobną regułą dla próbnych wstawek:
źródło
Upewnij się, że uruchomiłeś test z tymi samymi argumentami. Sprawdź, czy konfiguracje uruchamiania Intellij pasują do jenkins. https://www.jetbrains.com/help/idea/creating-and-editing-run-debug-configurations.html . Możesz spróbować uruchomić test na komputerze lokalnym z tymi samymi argumentami, co na jenkins (z terminala), jeśli się nie powiedzie, oznacza to, że problem jest w argumentach
źródło
org.mockito.plugins.MockMaker
istnieje również w maszynie Jenkinsa. Używam tej samej maszyny JVM w botach. Sprawdzę 3, które wskazałeś. Dzięki