如何在Scala的单元测试中使用模拟 [英] how to use mocking in unit testing in scala

查看:156
本文介绍了如何在Scala的单元测试中使用模拟的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是单元测试的新手,我想使用模拟对象对其进行测试。我想测试数据是否成功存储在mongoDB中
这是我的代码

hi i am new in Unit Testing and i want to test it using mock objects .i want to test whether data is successfully stored in mongoDB or not here is my code

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对象检查代码是否正确工作

make an scala object to check code is working correctlly

object Test extends App{

val directUser= new DirectUser() 

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

现在我想对DirectUserStore.scala类执行测试,因此在sbt的src / test diectory中,我创建了此类

Now i want to perform test on DirectUserStore.scala class ,So in src/test diectory of sbt i created this class

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中键入测试时,我的测试失败

but when i type test in sbt my test failed

[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 ***

请指导我如何我能实现我的目标吗。我知道我在犯一些大错误,但我需要指导,因此这是我一生中正在写的第一个测试
帮助

please guide me how can i achieve my goal . i know i am doing some big mistake but i need guidance hence its the first test i am writing in my life help please

推荐答案

您要成为Mongo客户开发人员吗?否则,在单元测试中将值存储在数据库中就没有任何意义(您可以在集成测试中做到这一点,但是我仍然看不到任何要点)。
以可移植性为例-假设在默认地址上存在MongoDB的单元测试将在未安装MongoDB的任何其他计算机上失败。
其次-您必须假设某些事情正在运行-因此,假设MongoDB API可以正常工作-是一个有效的假设。否则,您可能会质疑所有问题(字符串连接是否起作用?为什么信任一个库而不是另一个库?)-我想您明白我的意思了

Are you going to be Mongo client developer? Otherwise there is no point in testing if the value get stored in the DB in Unit Tests (you can do this in Intergration test, but I don't see a point anyway). Think for example of portability - unit tests assuming existence of MongoDB on default address will fail on any other computer without a MongoDB installed. Secondly - You have to assume some things are working - and hence that assumption that MongoDB API works as it should - is a valid assumption. Otherwise you can question everything (is string concatenation working or not? Why trust one library over another?) - I guess you see my point

您应该实际测试的是您将正确的值传递给Mongo API。这可以通过嘲笑来完成。
您可以使用 ScalaMock ,而我更喜欢使用 Mockito ,因为它可与Scala配合使用并具有更多可用功能。

What you should actually test is whether you pass the correct values to the Mongo API. This can be done by mocking. You can use ScalaMock while I prefer to use Mockito as it works well with Scala and have more functionality available. No problems with combining those two if you need.

您的类 directUserStore 对某些可以替换的类具有不可替代的依赖关系,

Your class directUserStore has unreplacable dependecies to some classes that can't be changes and therefore easily mocked - for example serverAddress and client - they can be moved to class level ones. Then, you can override them with a mock (generated for example by Mockito), which will return another mock of collection and verify, if the correct methods were called on that collection.

这篇关于如何在Scala的单元测试中使用模拟的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆