Ich konfrontiert mit einem Problem, wenn versuchen, BDD-Ansatz mit Scalatest und Mockito zu verwenden. Um die Code-Duplizierung zu reduzieren, gebe ich jede benötigte Regel an, wenn() in jedem beschreibenden Block steht. Aber ich war überrascht von der Reihenfolge, wie die describe() - Blöcke laufen.Scala FunSpec testet desribe() Initialisierung und Ausführungsreihenfolge
class SomeTest extends FunSpec with BeforeAndAfterAll with MockitoSugar {
private val catalogClient = mock[CatalogServiceClient]
override def beforeAll {
when(catalogClient.getFrame(any)).thenReturn(Frame())
}
describe("MyTest1") {
println("Inside MyTest1")
when(catalogClient.getConnection(any))
.thenReturn(Conn(ID_FOR_TEST_1))
it("should perform action with data ID_FOR_TEST_1") {
println("Inside it 1")
}
it("should perform another action with data ID_FOR_TEST_1") {
///
}
}
describe("MyTest2") {
println("Inside MyTest2")
when(catalogClient.getConnection(any))
.thenReturn(Conn(ID_FOR_TEST_2))
it("should perform logic with data ID_FOR_TEST_2") {
println("Inside it 2")
}
it("should perform another logic with data ID_FOR_TEST_2") {
///
}
}
}
Es gedruckt:
"Inside MyTest1"
"Inside MyTest2"
"Inside it 1"
"Inside it 2"
während ich
"Inside MyTest1"
"Inside it 1"
"Inside MyTest2"
"Inside it 2"
Und der erste Test schlug fehl, da verspottete Daten ersetzt in dem zweiten describe() Block zu erwarten.
Also zuerst geht es durch alle beschreiben Blöcke und danach führen Sie die Tests.
Nach einiger Forschung, fand ich path.FunSpec
Klasse, die Bestellung von jedem Block beschreiben bewahrt, aber es macht keinen Gebrauch Eigenschaften wie BeforeAndAfter
wegen der überwiegenden runTest()
Verfahren als endgültig ermöglichen.
Ich möchte einige gute Praktiken kennen, um solche Tests mit minimaler Codeverdopplung zu organisieren. Und einige Empfehlungen zu meinem speziellen Fall.
Ich habe mein Beispiel aktualisiert. So, jetzt habe ich eine gemeinsame Variable CatalogClient Mock, und allgemeine Mock-Regeln in BeforeAll() für alle Tests. > Um das Problem zu lösen, lassen Sie jeden Test eine eigene Version des mocked-Objekts erstellen. Meinst du ich sollte jede spezifische When() Definition in jedem von ihm() Test setzen? Es besteht also immer noch die Fallcode-Duplizierung. – oleffir
Nein, der Aufruf zu "Mock" muss für jeden Test erfolgen. Sie können natürlich eine Funktion extrahieren, aber im Moment haben Sie nur eine Instanz für die gesamte Klasse. – Kraylog