2017-01-26 2 views
1

Ich möchte einen Test in Scala einrichten, der eine Mock-Konfiguration erstellt, um bestimmte Werte bereitzustellen. Ich verwende ScalaTest 3.0.1, ScalaMock 3.4.2, und typsichere 1.3.1. Das Ziel besteht darin, vor dem Ausführen von Tests Werte für die Konfiguration zu übernehmen. Die Dokumente http://www.scalatest.org/user_guide/testing_with_mock_objects und http://scalamock.org/user-guide/features/ scheinen bieten ein paar Optionen. Erstens, hier einiger Zielcode:Wie richte ich eine ScalaMock einmal für wiederholte Methodenaufrufe ein?

import com.typesafe.config.Config 
class Sample(config: Config) { 
    private val aValue = config.getDouble("aValue") 
} 

Es scheint, wie sollte es möglich sein, alles zu setzen eine Zeit, oder alles, was vor jedem Test einzurichten. Dieser Versuch schlägt fehl:

class SampleSpec extends FlatSpec with MockFactory with BeforeAndAfterAll { 

    private val mockConfig = mock[Config] 

    override def beforeAll { 
    (mockConfig.getDouble _).expects("aValue").returning(1.0).anyNumberOfTimes() 
    } 

    "testOne" should "return 1" in { 
    new Sample(mockConfig) 
    } 

    "testTwo" should "return 1" in { 
    new Sample(mockConfig) 
    } 

} 

Der erste Test ist erfolgreich, aber zweiter Test in der Halterung aus, und dieser Fehler erzeugt wird:

Unexpected call: <mock-1> Config.getDouble(aValue) 

Expected: 
inAnyOrder { 

} 

Actual: 
    <mock-1> Config.getDouble(aValue) 
ScalaTestFailureLocation: scala.Option at (Option.scala:120) 
org.scalatest.exceptions.TestFailedException: Unexpected call: <mock-1> Config.getDouble(aValue) 

Expected: 
inAnyOrder { 

} 

Hier ist ein alternativer Ansatz:

class SampleSpec extends FlatSpec with MockFactory with BeforeAndAfter { 

    private val mockConfig = mock[Config] 

    before { 
    (mockConfig.getDouble _).expects("aValue").returning(1.0) 
    } 

    "testOne" should "return 1" in { 
    new Sample(mockConfig) 
    } 

    "testTwo" should "return 1" in { 
    new Sample(mockConfig) 
    } 

} 

Es produziert diese Ausnahme:

An exception or error caused a run to abort: assertion failed: Null expectation context - missing withExpectations? 
java.lang.AssertionError: assertion failed: Null expectation context - missing withExpectations? 

Warum schlägt der erste Versuch fehl? Der Test gibt an, dass getDouble beliebig oft aufgerufen werden kann, aber der zweite Test schlägt fehl, als ob anyNumberOfTimes() nicht verwendet wurde. Wie sollte dies codiert werden, so dass die Methode einmal verspottet und wiederholt aufgerufen werden kann? Warum scheitert der zweite Versuch? Gibt es eine Methode, um den Mock zurückzusetzen, damit er wiederverwendet werden kann?

Antwort

1

Ich würde auch die Dokumentation Seite für diese darauf hinweisen, mit einem etwas anderen Stil (mit einem Zug):

http://scalamock.org/user-guide/sharing-scalatest/#fixture-contexts

Zum Beispiel:

class SampleSpec extends FlatSpec with OneInstancePerTest with MockFactory { 

    private val mockConfig = mock[Config] 

    (mockConfig.getDouble _).expects("aValue").returning(1.0).anyNumberOfTimes 

    "testOne" should "return 1" in { 
    new Sample(mockConfig) 
    } 

    "testTwo" should "return 1" in { 
    new Sample(mockConfig) 
    } 

} 
+0

Ich habe die erste Technik (OneInstancePerTest) angewendet, und so besser. Ich habe Dokumente dafür woanders gesehen, aber diese Erklärung ist klarer. Bearbeiten, um ein Beispiel zu geben ... –

1

die mock jedes Mal neu erstellen, manuell die einzige Art, wie ich es an der Arbeit kann:

class SampleSpec extends FlatSpec with MockFactory { 

    private def mockConfig = { 
    val mocked = mock[Config] 
    (mocked.getDouble _).expects("aValue").returning(1.0).anyNumberOfTimes() 
    mocked 
    } 

    "testOne" should "return 1" in { 
    new Sample(mockConfig) 
    } 

    "testTwo" should "return 1" in { 
    new Sample(mockConfig) 
    } 

} 

, die einfach ist, weil die Tests alle nicht ändern. Sie verschieben einfach die Logik von der "global local" -Variablen in den lokalen Bereich eines einzelnen Tests.

+0

Oh, interessant . Ich habe versucht, es in einem Vorher-Block neu zu erstellen, aber hatte den gleichen Fehler wie mein Versuch 2 in der Frage. –

+0

Ich mag deine Antwort. Bearbeitet um einen Kontext um das Setup hinzuzufügen. –

Verwandte Themen