4

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!

  • 3
    Just make the object implement a trait and then use dependency injection instead of referring to the object directly. –  Aug 06 '15 at 07:55
  • Can you make some code examples for clearly understanding? – Bogdan Drachinskiy Aug 06 '15 at 08:03
  • I've made something like this `object Category extends MongoBase[Category]("categories") with MyCategory` `class MyNewCategory { val service: MyCategory = Category }` `trait MyCategory { def test = 42 }` And made test: `val mockCategory = mock[MyCategory] val category = new MyNewCategory { override val service = mockCategory } category.service.test returns 222 category.service.test must beEqualTo(42)` This is another failed test cause Category trying to connect with mongo – Bogdan Drachinskiy Aug 06 '15 at 10:10

1 Answers1

4

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...


}
vvg
  • 6,325
  • 19
  • 36