Reputation: 3505
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 = "[email protected]"
secondryEmail =Some("[email protected]")
userStatus =ACTIVE
}
And here is the class which i want to test
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())
)
}
}
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)
}
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)
}
}
}
}
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
Upvotes: 0
Views: 2252
Reputation: 21184
You don't want mocking at this level of code. Your directUserStore class is responsible for interacting with MongoDb, storing and retrieving data. Mocking out MongoDb will only tell you that you've interacted with the Mongo API in the way that you think you should, not necessarily the right way.
What you should do here is spin up a MongoDb instance and round-trip your data. If you only care that the data can be stored and read, just write it/read it back and verify it. If you really care about how it's stored (hint: you probably don't) then you will have to poke MongoDb manually in the tests.
Upvotes: 0
Reputation: 12024
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
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.
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.
Upvotes: 3