模拟 scala 对象

发布于 2024-09-16 17:55:13 字数 477 浏览 11 评论 0原文

我正在使用 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 从对象更改为类,它就会起作用。 是否可以用mockito模拟scala对象?如果是的话怎么办?

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]
     }
}

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

作业与我同在 2024-09-23 17:55:13

正如所写,您的 Sample 是一个纯单例。它的类型是它自己的,并且该类型只有一个成员,即句点。 Scala 对象可以扩展另一个类(可能是抽象的,如果它提供必要的定义使其成为具体的)和特征。这样做会给它一个包含这些祖先的类型标识。

我不知道 Mockito 到底在做什么,但在我看来,您所要求的与 Scala object 的含义完全不一致。

As written, your Sample is a pure singleton. Its type is its own and there is only one member of that type, period. Scala objects can extend 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.

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

心如狂蝶 2024-09-23 17:55:13

请记住,如果将对象方法提升为函数,您可以模拟它们。

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

Keep in mind that you can mock the methods of an object if you lift them to functions.

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

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 ClassUnderTest is simply new ClassUnderTest due to the injected function being a default argument.

策马西风 2024-09-23 17:55:13

从mockito-scala版本1.16.0开始,可以模拟Scala对象,您可以查看文档此处,但这是它的外观示例。

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!"
 }
}

Since version 1.16.0 of mockito-scala it is possible to mock Scala objects, you can check the docs here, but this is an example of how it would look like.

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!"
 }
}
陪你搞怪i 2024-09-23 17:55:13

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

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文