2017-12-12 5 views
1

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.

Antwort

1

Standardmäßig führt scalatest die Tests parallel durch, um die Testzeit zu verkürzen.

Die Tatsache, dass Sie dieses Problem haben, verweist auf ein anderes Problem, das Sie haben, und zum Glück gestolpert sind - Ihre Tests sind nicht isoliert.

Um das Problem zu lösen, lassen Sie jeden Test seine eigene Version des Mocked-Objekts erstellen. Wenn Sie die Code-Duplizierung reduzieren möchten, hat scalatest Hooks, die Code vor jedem Test ausführen können.

+0

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

+0

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

Verwandte Themen