【问题标题】:How to pass a scala class in a mock如何在模拟中通过 Scala 类
【发布时间】:2020-01-28 09:08:41
【问题描述】:

我有一个 scala 类 A,其中有一个方法 doSomething

还有一个B类

  class B(name: String)

还有一个C类

class C {
 def doSomethingElse(b: B): String { 
 /// some logic 

 ////

 }
} 


 class A(c: C) {
  def doSomething(uuid: UUID): String {
   val b = new B("hello)
   c.doSomethingElse(b)
   // some logic

 }

}

现在我想使用 scalatest 和 scalamock 测试 A 类的方法 doSomething

我试图模拟通话doSomethingElse

val mockC = mock[C] 
val b = new B("hello")
(mockC.doSomethingElse _).expects(b).returning("A");

但是当实际调用发生时,模拟不会得到满足,因为B 的对象不同。有没有办法表达这个模拟,让它得到满足?

【问题讨论】:

  • 如果您希望new B("hello") 被视为与另一个new B("hello") 相同,则必须相应地实现.equals。默认情况下,使用 Java 实例标识(只有同一个实例是相等的)。如果B 可以是案例类,您可以免费获得。

标签: scala scalatest scalamock


【解决方案1】:

Thilo 的评论是正确的 - 您的两个 Bs 将作为上面的引用进行比较,并且由于它们不是同一个对象,因此它们不相等。对于内容平等,您需要一个适当的equals 实现。如果您将 B 设为 case class,您可以在 Scala 中免费获得它。如果您无法更改 B 类,那么在 ScalaMock 中使用谓词数学可能会帮助您在测试期间比较两个实例。在这里阅读它:https://scalamock.org/user-guide/matching/

【讨论】:

  • 但我的不是案例类,它不一定只是为了让测试通过。还有其他只能用于测试的技巧吗?
  • 您是否按照我上面的建议阅读并尝试了谓词匹配器?如果这对您不起作用,那么从根本上说,这就是 JVM 的工作方式。
【解决方案2】:

以下是@Thilo 和@PhilippM 建议的示例:

像这样覆盖equals方法

class B(val name: String) {
  override def equals(obj: Any): Boolean = obj match {
    case b: B => b.name == this.name
    case _ => false
  }
}

我们可以使用正则

(mockC.doSomethingElse _) expects(new B("hello")) returning("A")

或者如果我们不能修改B,那么试试predicate matching 像这样

mockC.doSomethingElse _ expects where { (b: B) => b.name == new B("hello").name } returning "A"

【讨论】:

    猜你喜欢
    • 2019-11-07
    • 2021-11-30
    • 1970-01-01
    • 2015-01-22
    • 1970-01-01
    • 2018-12-22
    • 1970-01-01
    • 2016-09-25
    • 1970-01-01
    相关资源
    最近更新 更多