Ich habe einige Unit-Tests für eine statische Methode geschrieben. Die statische Methode akzeptiert nur ein Argument. Der Typ des Arguments ist eine letzte Klasse. In Bezug auf Code:
public class Utility {
public static Optional<String> getName(Customer customer) {
// method's body.
}
}
public final class Customer {
// class definition
}
Also habe Utility
ich für die Klasse eine Testklasse erstellt, UtilityTests
in der ich Tests für diese Methode geschrieben habe getName
. Das Unit-Test-Framework ist TestNG und die verwendete Mocking-Bibliothek ist Mockito
. Ein typischer Test hat also folgende 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(...);
}
}
Was ist das Problem ?
Während die Tests lokal erfolgreich ausgeführt werden, schlagen sie in IntelliJ auf Jenkins fehl (wenn ich meinen Code in den Remote-Zweig schiebe, wird ein Build ausgelöst und am Ende werden Komponententests ausgeführt). Die Fehlermeldung lautet wie folgt:
org.mockito.exceptions.base.MockitoException: Klasse / Spion-Klasse kann nicht verspottet werden com.packagename.Customer Mockito kann nicht verspotten / spionieren, weil: - letzte Klasse
Was habe ich versucht?
Ich habe ein bisschen gesucht, um eine Lösung zu finden, aber ich habe es nicht geschafft. Ich stelle hier fest, dass ich die Tatsache, dass es sich um eine Abschlussklasse handelt, nicht ändern darf . Darüber hinaus möchte ich, wenn möglich, das Design überhaupt nicht ändern (z. B. eine Schnittstelle erstellen, die die Methoden enthält, die ich verspotten möchte, und angeben, dass die Customer-Klasse diese Schnittstelle implementiert, wie Jose in seinem Bericht korrekt ausgeführt hat Kommentar). Das, was ich versucht habe, ist die zweite Option, die im Mockito-Finale erwähnt wurde . Trotz der Tatsache, dass dies das Problem behoben hat, bremst es einige andere Unit-Tests :(, die nicht auf offensichtliche Weise behoben werden können.Customer
Fragen
Hier sind die beiden Fragen, die ich habe:
- Wie ist das überhaupt möglich? Sollte der Test nicht sowohl lokal als auch in Jenkins fehlschlagen?
- Wie kann dies aufgrund der oben genannten Einschränkungen behoben werden?
Vielen Dank im Voraus für jede Hilfe.
quelle
enable final
Konfiguration in Ihrem Arbeitsbereich funktioniert, aber wenn sie ausgeführt wirdJenkins
, kann sie diese Datei nicht finden. Überprüfen Sie, woJenkins
nach der Datei gesucht wird und ob sie tatsächlich vorhanden ist oder nicht.Customer
es irgendeine Logik oder ist es nur eine dumme Datenklasse? Wenn es sich nur um eine Reihe von Feldern mit Getter und Setter handelt, können Sie es einfach instanziieren.Antworten:
Ein alternativer Ansatz wäre die Verwendung des Musters "Methode zum Klassifizieren".
Hier ist ein guter Blog zum Thema: https://simpleprogrammer.com/back-to-basics-mock-eliminating-patterns/
quelle
Es ist offensichtlich eine Art Umwelt-Besonderheiten. Die Frage ist nur, wie die Ursache des Unterschieds ermittelt werden kann.
Ich würde Ihnen empfehlen, die
org.mockito.internal.util.MockUtil#typeMockabilityOf
Methode zu überprüfen und zu vergleichen, wasmockMaker
in beiden Umgebungen tatsächlich verwendet wird und warum.Wenn
mockMaker
das gleiche ist - vergleichen geladene KlassenIDE-Client
vsJenkins-Client
- haben sie einen Unterschied zu der Zeit der Testausführung.Der folgende Code wurde unter der Annahme von OpenJDK 12 und Mockito 2.28.2 geschrieben, aber ich glaube, Sie können ihn an jede tatsächlich verwendete Version anpassen.
Mit einer separaten Regel für Inline-Mocks:
quelle
Stellen Sie sicher, dass Sie den Test mit denselben Argumenten ausführen. Überprüfen Sie, ob Ihre Intellij-Laufkonfigurationen mit den Jenkins übereinstimmen. https://www.jetbrains.com/help/idea/creating-and-editing-run-debug-configurations.html . Sie können versuchen, den Test auf einem lokalen Computer mit denselben Argumenten wie auf Jenkins (vom Terminal) auszuführen. Wenn dies fehlschlägt, liegt das Problem in Argumenten
quelle
org.mockito.plugins.MockMaker
existiert auch in Jenkins Maschine. Ich benutze die gleiche JVM in Bot-Maschinen. Ich werde die 3 überprüfen, auf die Sie hingewiesen haben. Danke