Wie verwalte ich die unit test Ressourcen in Kotlin, wie das starten/stoppen Sie eine Datenbank-Verbindung oder eine eingebettete elasticsearch server?
In meinem Kotlin JUnit-tests, ich möchte die start/Stopp-embedded-Server und verwenden Sie Sie innerhalb meiner tests.
Versuchte ich mit JUnit @Before
annotation an einer Methode in meiner test-Klasse und es funktioniert gut, aber es ist nicht das richtige Verhalten, da läuft jeder test statt nur einmal.
Daher möchte ich die @BeforeClass
annotation an einer Methode, aber indem es um eine Methode, führt zu einer Fehlermeldung, die sagen, es muss über eine statische Methode. Kotlin, scheint noch nicht in statischen Methoden. Und dann das gleiche gilt für statische Variablen, weil ich brauche, um einen Verweis auf den embedded-server, um für den Einsatz in den test-Fällen.
Also wie erstelle ich diese eingebettete Datenbank nur einmal für alle meine Testfälle?
class MyTest {
@Before fun setup() {
//works in that it opens the database connection, but is wrong
//since this is per test case instead of being shared for all
}
@BeforeClass fun setupClass() {
//what I want to do instead, but results in error because
//this isn't a static method, and static keyword doesn't exist
}
var referenceToServer: ServerType //wrong because is not static either
...
}
Hinweis: diese Frage ist absichtlich geschrieben und beantwortet der Autor (Selbst Beantwortete Fragen), so dass die Antworten auf Häufig gestellte Kotlin Themen vorhanden sind, in SO.
- JUnit 5. Mai die Unterstützung von nicht-statischen Methoden, die für diesen Anwendungsfall finden Sie unter github.com/junit-team/junit5/issues/419#issuecomment-267815529 und fühlen Sie sich frei, um +1 mein Kommentar zu zeigen, Kotlin-Entwickler daran interessiert sind, solche Verbesserungen.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ihre unit-test-Klasse muss in der Regel ein paar Dinge, die zum verwalten einer freigegebenen Ressource für eine Gruppe von test-Methoden. Und in Kotlin, die Sie verwenden können
@BeforeClass
und@AfterClass
nicht in der test-Klasse, sondern innerhalb seiner companion-Objekt zusammen mit der@JvmStatic
annotation.Den Aufbau einer test-Klasse würde wie folgt Aussehen:
Angesichts der oben genannten, sollten Sie Lesen Sie über:
@JvmStatic
- eine Anmerkung, die dreht sich eine companion-Objekt die Methode in einer statischen Methode auf die äußere Klasse für Java-interoplateinit
- ermöglicht einevar
Eigenschaft initialisiert werden später, wenn Sie eine gut definierte lifecycle -Delegierten.notNull()
- kann anstelle von verwendet werdenlateinit
für eine Eigenschaft, die gesetzt werden sollten, mindestens einmal, bevor Sie gelesen werden.Hier sind voller Beispiele von test-Klassen für Kotlin, dass die Verwaltung eingebetteter Ressourcen.
Den ersten kopiert und geändert von Solr-Sog tests, und bevor die Testfälle ausgeführt werden, konfiguriert und gestartet wird, ein Solr-Undertow-server. Nach dem ausführen der tests, es löscht alle temporären Dateien, die erstellt durch die tests. Es sorgt auch für environment-Variablen und system-Eigenschaften korrekt sind, bevor die tests ausgeführt werden. Zwischen test cases, es leert alle temporären geladen Solr-Kerne. Der test:
Und anderen ab AWS DynamoDB local als eine eingebettete Datenbank (kopiert und leicht modifiziert aus Laufen AWS DynamoDB-lokal eingebettete). Dieser test muss der hack
java.library.path
bevor irgendetwas anderes passiert, oder lokale DynamoDB (sqlite mit binären Bibliotheken) wird nicht ausgeführt. Dann startet er einen server zu teilen, für alle test-Klassen und bereinigt, temporäre Daten, die zwischen den tests. Der test:HINWEIS: einige Teile der Beispiele sind abgekürzt mit
...
Verwaltung von Ressourcen mit vor/nach Rückrufe in tests, natürlich hat es Vorteile:
Es einige Nachteile hat auch. Eine wichtige davon ist, dass es verschmutzt den code und lässt den code gegen das Prinzip der einzigen Verantwortung. Tests jetzt nicht nur etwas testen, aber führen Sie ein Schwergewicht Initialisierung und Ressourcen-management. Es kann ok sein, in manchen Fällen (wie konfigurieren eines
ObjectMapper
), aber ändernjava.library.path
oder Laich einem anderen Verfahren (oder in-Prozess-embedded-Datenbanken) sind nicht so unschuldig.Warum nicht behandeln Sie die Dienstleistungen, die als Abhängigkeiten für den test qualifiziert für "injection", wie beschrieben von 12factor.net.
Diese Weise Sie starten und initialisieren Abhängigkeit Dienste, die irgendwo außerhalb der test-code.
Heutzutage Virtualisierung und Container sind fast überall und die meisten Entwickler-Maschinen sind in der Lage zu laufen Docker. Und die meisten von der Anwendung eine dockerized version: Elasticsearch, DynamoDB, PostgreSQL und so weiter. Docker ist eine perfekte Lösung für externe Dienstleistungen, dass Ihre tests benötigen.
dependsOn
undfinalizedBy
DSL für die Definition von Abhängigkeiten). Eine Aufgabe, natürlich, ausführen können das gleiche script, dass Entwickler wird ausgeführt manuell mit dem shell-outs /Prozess execs.Diesen Ansatz:
Natürlich, es hat Fehler (im Grunde, die Aussagen, die ich angefangen habe, aus):