Search code examples
scalaunit-testingmockitospecs2

How to mock an Object in Scala


I'm new with scala. I'm trying to UT method inside my object Category, using Specs2 for UT and Mockito for mock. Why should I mock this? because this method take some data from mongo. There is my example

object Category extends MongoBase[Category]("categories") {
....
def myMethod(str: String): String
....
}

I've tried to mock object this way:

val mockCategory = mock[Category.type]
mockCategory.myMethod("1") returns "2"

But my test failed

   Cannot mock/spy class 
Mockito cannot mock/spy following:
  - final classes
  - anonymous classes
  - primitive types
org.mockito.exceptions.base.MockitoException: 
Cannot mock/spy class
Mockito cannot mock/spy following:
  - final classes
  - anonymous classes
  - primitive types
    at CategoryMockSpec.mock(CategoryMockSpec.scala:14)
    at CategoryMockSpec$$anonfun$1$$anonfun$apply$1.apply(CategoryMockSpec.scala:18)
    at CategoryMockSpec$$anonfun$1$$anonfun$apply$1.apply(CategoryMockSpec.scala:16)

Thanks for any advice!


Solution

  • Try to move all behavior, that you need to test into class or trait level. You'll be able to mixin different implementation in production code and test code.

    For example:

    trait CategoryApi {
      def importantMethod: Int 
    }
    
    class Category extends MongoBase[Category]("categories") with CategoryApi {
      override def importantMethod = { /*go to mongo for real data*/ }
    }
    
    class CategoryTest with CategoryApi {
      override def importantMethod = 42
    }
    
    // service which uses categories
    
    class SomeService(catApi: CategoryApi) {
      def methodToTest = {
        importantMethod
      }
    }
    
    // your test
    
    test() {
    
    val service = new SomeService(CategoryTest())
    service.methodToTest == 42 // return 42...
    
    
    }