Mocking scala object

sco*_*out 13 specs scala mocking object mockito

I am using mockito and trying to mock a scala object.

object Sample { }
//test
class SomeTest extends Specification with ScalaTest with Mockito {
    "mocking should succeed" in {
        val mockedSample = mock[Sample]
     }
}
Run Code Online (Sandbox Code Playgroud)

这给了我两个编译错误.

error: Not found type Sample
error: could not find implicit value for parameter m:
scala.reflect.ClassManifest[<error>]
Run Code Online (Sandbox Code Playgroud)

如果我将Sample从对象更改为类,则可以正常工作.有可能用mockito模拟scala对象吗?如果有,怎么样?

Ran*_*ulz 10

如上所述,你Sample是一个纯粹的单身人士.它的类型是它自己的,只有一个类型的成员,句号.斯卡拉object小号扩展另一个类(可能是抽象的,如果它提供必要的定义,使其具体)和特质.这样做会给它一个包含那些祖先的类型标识.

我不知道Mockito到底在做什么,但在我看来,你要求的东西与Scala的object内容完全不一致.

  • 绝对同意这里.您可以尝试模拟[Sample.type],但我怀疑它会在实践中起作用.我建议让Sample扩展一些接口特性并以这种方式嘲笑它.最大的问题是,如果你想注射你的模拟代替单例样本,你将不得不做一些漂亮,邪恶,有趣的反思魔法.如果您有兴趣,我们可以发布. (3认同)

Syn*_*sso 8

请记住,如果将它们提升为函数,则可以模拟方法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)"
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

在这里,我不是在嘲笑对象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 ==
Run Code Online (Sandbox Code Playgroud)

同时,生产时间的使用ClassUnderTest仅仅是new ClassUnderTest由于注入的函数是默认参数.


Bru*_*uno 8

由于 mockito-scala 的 1.16.0 版可以模拟 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!"
 }
}
Run Code Online (Sandbox Code Playgroud)


Pau*_*her 5

我最近发布了ScalaMock,一个Scala的模拟库,除其他外,还可以模拟单例(和伴随)对象.

  • 在提供的页面上,对单身和伴侣对象的支持在标题为"未来计划"的部分下声明.框架目前是否支持这些功能? (5认同)
  • @Zotov,似乎对模拟对象的支持只能在ScalaMock2中使用2.9编译器插件,如本[教程]中所述(http://paulbutcher.com/2011/11/06/scalamock-step逐步骤/).ScalaMock3不需要编译器插件,因为它依赖于Scala 2.10宏,但它不支持ScalaMock2的所有功能,如[博客文章]中所述(http://paulbutcher.com/2012/ 6月4日/ scalamock-3-0-预览发布/).因此,在2.10中不支持模拟对象:据我所知,这似乎仍然是项目的当前状态. (3认同)
  • ScalaMock的当前文档直接与此答案相矛盾。请参阅“我可以模拟对象吗?” [FAQ](https://scalamock.org/user-guide/faq/)部分。 (2认同)