Насмешливый скала

Я использую 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 objects может расширять другой класс (возможно, абстрактный, если он предоставляет необходимые определения, чтобы сделать его конкретным) и признаки. Делая это, вы получаете идентичность типа, которая включает в себя этих предков.

Я не знаю, что на самом деле делает 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. objects, вы можете проверить документацию здесь, но это пример того, как это будет выглядеть.

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, которая, помимо прочего, может макетировать одиночные (и сопутствующие) объекты.

Другие вопросы по тегам