Насмешливый скала
Я использую mockito и пытаюсь издеваться над объектом scala.
object Sample { }
//test
class SomeTest extends Specification with ScalaTest with Mockito {
"mocking should succeed" in {
val mockedSample = mock[Sample]
}
}
Это дает мне две ошибки компиляции.
error: Not found type Sample
error: could not find implicit value for parameter m:
scala.reflect.ClassManifest[<error>]
Если я изменяю Sample от объекта к классу, это работает. Можно ли издеваться над объектами скалы с помощью мокито? Если да, то как?
3 ответа
Как написано, ваш Sample
это чистый синглтон. Его тип свой, и есть только один член этого типа, точка. Scala object
s может расширять другой класс (возможно, абстрактный, если он предоставляет необходимые определения, чтобы сделать его конкретным) и признаки. Делая это, вы получаете идентичность типа, которая включает в себя этих предков.
Я не знаю, что на самом деле делает Mockito, но, на мой взгляд, то, что вы просите, строго расходится с тем, что делает Scala object
является.
Имейте в виду, что вы можете издеваться над методами object
если вы поднимите их на функции.
case class Person(name: String)
object Person {
def listToJson(lp: List[Person]) = "some actual implementation"
}
class ClassUnderTest(listToJson: (List[Person]) => String = Person.listToJson(_)) {
def testIt(lp: List[Person]) = listToJson(lp)
}
import org.specs._
import org.specs.mock.Mockito
import org.mockito.Matchers._
class ASpec extends Specification with Mockito {
"a thing" should {
"do whatever" in {
val m = mock[(List[Person]) => String]
val subject = new ClassUnderTest(m)
m(Nil) returns "mocked!"
subject.testIt(Nil) must_== "mocked! (this will fail on purpose)"
}
}
}
Здесь я не издеваюсь над объектом Person, а над его методом (что, вероятно, и предполагал OP).
Результат теста показывает издевательские работы:
[info] == ASpec ==
[error] x a thing should
[error] x do whatever
[error] 'mocked![]' is not equal to 'mocked![ (this will fail on purpose)]' (ASpec.scala:21)
[info] == ASpec ==
Между тем, использование времени производства ClassUnderTest
это просто new ClassUnderTest
из-за того, что введенная функция является аргументом по умолчанию.
Начиная с версии 1.16.0 mockito-scala, появилась возможность имитировать Scala.
object
s, вы можете проверить документацию здесь, но это пример того, как это будет выглядеть.
object FooObject {
def simpleMethod: String = "not mocked!"
}
"mock" should {
"stub an object method" in {
FooObject.simpleMethod shouldBe "not mocked!"
withObjectMocked[FooObject.type] {
FooObject.simpleMethod returns "mocked!"
//or
when(FooObject.simpleMethod) thenReturn "mocked!"
FooObject.simpleMethod shouldBe "mocked!"
}
FooObject.simpleMethod shouldBe "not mocked!"
}
}
Недавно я выпустил ScalaMock, библиотеку-макет для Scala, которая, помимо прочего, может макетировать одиночные (и сопутствующие) объекты.