Как издеваться над объектом в Scala

Я новичок в скале. Я пытаюсь использовать метод UT внутри своей категории объектов, используя Specs2 для UT и Mockito для имитации. Почему я должен издеваться над этим? потому что этот метод берет некоторые данные из монго. Вот мой пример

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

Я пытался издеваться над объектом следующим образом:

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

Но мой тест провалился

   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)

Спасибо за любой совет!


person Bogdan Drachinskiy    schedule 06.08.2015    source источник
comment
Просто заставьте объект реализовать трейт, а затем используйте внедрение зависимостей вместо прямого обращения к объекту.   -  person rightfold    schedule 06.08.2015
comment
Можете ли вы сделать несколько примеров кода для ясного понимания?   -  person Bogdan Drachinskiy    schedule 06.08.2015
comment
Я сделал что-то вроде этого object Category extends MongoBase[Category]("categories") with MyCategory class MyNewCategory { val service: MyCategory = Category } trait MyCategory { def test = 42 } И сделал тест: val mockCategory = mock[MyCategory] val category = new MyNewCategory { override val service = mockCategory } category.service.test returns 222 category.service.test must beEqualTo(42) Это еще один неудачный тест, потому что категория пытается соединиться с монго   -  person Bogdan Drachinskiy    schedule 06.08.2015


Ответы (1)


Попробуйте перенести все поведение, которое вам нужно протестировать, на уровень класса или черты. Вы сможете смешивать различные реализации в производственном коде и тестовом коде.

Например:

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


}
person vvg    schedule 06.08.2015