2017-01-26 53 views
1

我想在Scala中建立一個測試,創建一個模擬配置來提供某些值。我正在使用ScalaTest 3.0.1,ScalaMock 3.4.2, 和1.3a類型安全。目標是在運行測試之前模擬配置值。在 http://www.scalatest.org/user_guide/testing_with_mock_objectshttp://scalamock.org/user-guide/features/似乎提供 幾個選項的文檔。首先,這裏的一些目標代碼:如何爲重複的方法調用設置一次ScalaMock?

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

現在看來似乎應該是可能的設置一切有一段時間,或設置每次測試之前一切。該嘗試失敗:

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) 
    } 

} 

第一測試成功,但在夾具第二測試失敗,併產生這樣的錯誤:

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 { 

} 

下面是一個替代的方法:

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) 
    } 

} 

它產生此例外:

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? 

爲什麼第一次嘗試失敗?該測試指定getDouble可以被調用任意次數,但第二個 測試失敗,就好像沒有使用anyNumberOfTimes()一樣。應該如何編碼以便該方法可以被嘲笑一次並且重複地調用 ?爲什麼第二次嘗試失敗?有沒有一種方法來重置模擬,以便它可以重複使用?

回答

1

我還想指出的文檔頁面此,有一個稍微不同的風格(使用性狀):

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

例如:

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

我應用了第一種技術(OneInstancePerTest),並且更好。我在其他地方看到過這方面的文檔,但是這個解釋更清楚。編輯以提供示例... –

1

重新創建模擬每一次,手動是唯一的出路,我可以得到它的工作:這是很容易,因爲你的測試並沒有改變

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) 
    } 

} 

。您只是將邏輯從「全局本地」變量移動到單個測試的本地範圍內。

+0

呵呵,有意思。我試圖在前一個塊中重新創建它,但是在問題中出現了與我嘗試2相同的錯誤。 –

+0

我喜歡你的答案。編輯添加一些環境設置。 –

相關問題