簡體   English   中英

如何在Scala的單元測試中使用模擬

[英]how to use mocking in unit testing in scala

嗨,我是單元測試的新手,我想使用模擬對象對其進行測試。我想測試數據是否成功存儲在mongoDB中,這是我的代碼

package models.RegularUserModels
import models.UserModels.UserStatus._
// User will give information to Signup  

    class DirectUser() extends RegularUser{
      override val uuid = "direct123"
       override val firstName ="sara"
       lastName = "waheed"
       email = "user@example.com"
       secondryEmail  =Some("user2@example.com") 

        userStatus =ACTIVE

     }

這是我要測試的課程

package models.RegularUserModels

import com.mongodb.casbah.Imports._
import com.mongodb.QueryBuilder

class directUserStore {
  def write(directuser:DirectUser) ={
    val serverAddress=new ServerAddress("Localhost",27017)
    val client= MongoClient(serverAddress)

   val CourseDB = client("arteciatedb")//get database Name
    val collection = CourseDB("directUser")//get collection Name

    collection.drop()

        collection.insert(new BasicDBObject("_id",directuser.uuid)
                        .append("Email",directuser.email)
                        .append("SecondryEmail",directuser.secondryEmail)
                        .append("FirstName",directuser.firstName)
                        .append("LastName",directuser.lastName)
                        .append("UserStatus",directuser.userStatus.toString())
                        )

  }

}

制作一個scala對象以檢查代碼是否正確運行

object Test extends App{

val directUser= new DirectUser() 

/////////////////////////DirectUser mongo DB//////////////////////////
//insert in mongoDB
val directUserStore= new directUserStore
directUserStore.write(directUser)
}

現在我想對DirectUserStore.scala類執行測試,因此在src的src / test diectory中,我創建了此類

package testingModels.RegularUserModels
import models._
import models.RegularUserModels._
import org.scalatest.Matchers._
import org.scalatest.MustMatchers._
import org.scalatest.Spec
import org.scalatest.FunSpec
import org.easymock.EasyMock._
import org.scalatest.mock.EasyMockSugar

class DirectUserStoreTest extends FunSpec with org.scalatest.MustMatchers with EasyMockSugar {
    describe("A DirectUserStoreTest"){
      it("should use easy mock to mock out the DAO classes")
      {
        val DirectUserMock= createMock(classOf[directUserStore])
       /* val directUserStore= new directUserStore
        //replay, more like rewind
        replay(DirectUserMock)
        //make the call
        directUserStore.write(DirectUserMock)
        //verify that the calls expected were made
         verify(DirectUserMock)
*/      val directUser = new DirectUser 

        expecting{
        DirectUserMock.write(directUser)  
        }
        whenExecuting(DirectUserMock) {
        val directUserStore= new directUserStore
        directUserStore.write(directUser)

          }
      }
    }
}    

但是當我在sbt中鍵入test時,我的測試失敗了

[info] DirectUserStoreTest:
[info] A DirectUserStoreTest
[info] - should use easy mock to mock out the DAO classes *** FAILED ***
[info]   java.lang.IllegalStateException: missing behavior definition for the preceding method call:
[info] directUserStore.write(models.RegularUserModels.DirectUser@1fe2433b)
[info] Usage is: expect(a.foo()).andXXX()
[info]   at org.easymock.internal.MocksControl.replay(MocksControl.java:173)
[info]   at org.easymock.EasyMock.replay(EasyMock.java:2074)
[info]   at org.scalatest.mock.EasyMockSugar$$anonfun$whenExecuting$2.apply(EasyMockSugar.scala:421)
[info]   at org.scalatest.mock.EasyMockSugar$$anonfun$whenExecuting$2.apply(EasyMockSugar.scala:420)
[info]   at scala.collection.IndexedSeqOptimized$class.foreach(IndexedSeqOptimized.scala:33)
[info]   at scala.collection.mutable.WrappedArray.foreach(WrappedArray.scala:35)
[info]   at org.scalatest.mock.EasyMockSugar$class.whenExecuting(EasyMockSugar.scala:420)
[info]   at testingModels.RegularUserModels.DirectUserStoreTest.whenExecuting(DirectUserStoreTest.scala:11)
[info]   at testingModels.RegularUserModels.DirectUserStoreTest$$anonfun$1$$anonfun$apply$mcV$sp$1.apply$mcV$sp(DirectUserStoreTest.scala:28)
[info]   at testingModels.RegularUserModels.DirectUserStoreTest$$anonfun$1$$anonfun$apply$mcV$sp$1.apply(DirectUserStoreTest.scala:14)
[info]   ...
[info] Run completed in 2 seconds, 50 milliseconds.
[info] Total number of tests run: 1
[info] Suites: completed 1, aborted 0
[info] Tests: succeeded 0, failed 1, canceled 0, ignored 0, pending 0
[info] *** 1 TEST FAILED ***

請指導我如何實現我的目標。 我知道我在犯一些大錯誤,但是我需要指導,因此這是我一生中寫的第一個測試,請幫忙

您要成為Mongo客戶開發人員嗎? 否則,在單元測試中將值存儲在數據庫中就毫無意義(您可以在集成測試中做到這一點,但我還是看不到一點)。 以可移植性為例-假設在默認地址上存在MongoDB的單元測試將在未安裝MongoDB的任何其他計算機上失敗。 其次,您必須假設某些事情正在起作用-因此,假設MongoDB API可以正常工作的假設是一個有效的假設。 否則,您可能會質疑所有問題(字符串連接是否有效?為什么信任一個庫而不是另一個庫?)-我想您明白我的意思了

您應該實際測試的是是否將正確的值傳遞給Mongo API。 這可以通過嘲笑來完成。 您可以使用ScalaMock,而我更喜歡使用Mockito,因為它可以與Scala一起很好地工作並且具有更多可用功能。 如果需要,將兩者結合起來不會有問題。

您的類directUserStore對某些無法更改的類具有不可替代的依賴關系,因此可以輕松地進行serverAddress (例如serverAddressclient ,它們可以移至類級別。 然后,您可以使用模擬(例如由Mockito生成)來覆蓋它們,該模擬將返回另一個模擬collection並進行驗證(如果對該集合調用了正確的方法)。

您不希望在此級別的代碼上進行模擬。 您的directUserStore類負責與MongoDb進行交互,存儲和檢索數據。 模擬出MongoDb只會告訴您您已經以您認為應該的方式與Mongo API進行了交互,而不一定是正確的方式。

您在這里應該做的是啟動一個MongoDb實例並往返傳輸數據。 如果您只關心可以存儲和讀取數據,則只需寫/讀回並進行驗證。 如果您真的在乎它的存儲方式(提示:您可能不知道),那么您將不得不在測試中手動撥入MongoDb。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM