模拟 Scala 对象

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3576272/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 02:22:43  来源:igfitidea点击:

Mocking scala object

scalaobjectmockingmockitospecs

提问by scout

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

我正在使用 mockito 并尝试模拟 scala 对象。

object Sample { }
//test
class SomeTest extends Specification with ScalaTest with Mockito {
    "mocking should succeed" in {
        val mockedSample = mock[Sample]
     }
}

This gives me two compilation errors.

这给了我两个编译错误。

error: Not found type Sample
error: could not find implicit value for parameter m:
scala.reflect.ClassManifest[<error>]

If I change Sample from object to class it works. Is is possible to mock scala objects with mockito? If yes how?

如果我将 Sample 从对象更改为类,它会起作用。是否可以使用 mockito 模拟 scala 对象?如果是如何?

回答by Randall Schulz

As written, your Sampleis a pure singleton. Its type is its own and there is only one member of that type, period. Scala objects canextend another class (possibly abstract, if it supplies the necessary definitions to make it a concrete) and traits. Doing that gives it a type identity that includes those ancestors.

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

I don't know what Mockito is really doing, but to my mind, what you're asking for is strictly at odds with what a Scala objectis.

我不知道 Mockito 真正在做什么,但在我看来,你所要求的与 Scalaobject是完全不一致的。

回答by Synesso

Keep in mind that you canmock the methodsof an objectif you lift them to functions.

请记住,如果将an的方法提升为函数,则可以模拟它们。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)"
    }
  }
}

Here I'm not mocking the object Person, but the method on it (which is probably what the OP was intending).

在这里,我不是在嘲笑对象 Person,而是在嘲笑它的方法(这可能是 OP 的意图)。

The test result shows the mocking works:

测试结果显示模拟工作:

[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 ==

Meanwhile, the production-time usage of the ClassUnderTestis simply new ClassUnderTestdue to the injected function being a default argument.

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

回答by Paul Butcher

I've recently released ScalaMock, a mocking library for Scala that can, among other things, mock singleton (and companion) objects.

我最近发布了ScalaMock,这是一个用于 Scala 的模拟库,除其他外,它可以模拟单例(和伴随)对象。