如何模拟返回类型返回的无返回类型的选项[SomeCaseClassDefinedInsideThisClass]

时间:2017-11-02 17:37:41

标签: scala scalamock

我希望这个测试能够通过:

import org.scalamock.scalatest.MockFactory
import org.scalatest.{FlatSpec, Matchers}


class FruitImpl {
  case class FruitName(name: String)
  def getFruitName: Option[FruitName] = {
    Some(FruitName("apple"))
  }
}

class FruitSpec extends FlatSpec with Matchers with MockFactory {
  val f = mock[FruitImpl]
  (f.getFruitName _).expects().returning(None)

  behavior of "getFruitName method"

  it should "return None" in {
    f.getFruitName should === (None)
  }
}

但它失败了:

[error] my/path/QuestionTest.scala:13: overriding method getFruitName in class FruitImpl of type => Option[this.FruitName];
[error]  method getFruitName has incompatible type
[error]   val f = mock[FruitImpl]
[error]               ^  

但这有效:

import org.scalamock.scalatest.MockFactory
import org.scalatest.{FlatSpec, Matchers}

case class FruitName(name: String)

class FruitImpl {
  def getFruitName: Option[FruitName] = {
    Some(FruitName("apple"))
  }
}

class FruitSpec extends FlatSpec with Matchers with MockFactory {
  val f = mock[FruitImpl]
  (f.getFruitName _).expects().returning(None)

  behavior of "getFruitName method"

  it should "return None" in {
    f.getFruitName should === (None)
  }
}

唯一的区别是案例类FruitName是在FruitImpl类之外定义的。为什么一个版本的代码失败而另一个版本没有?在第一个例子中应该怎么做才能解决错误?

1 个答案:

答案 0 :(得分:0)

在没有查看ScalaMock代码的情况下,我会说模拟不是OO意义上FruitImpl的真正推导。它的目的是允许方法拦截,因此它只处理 facade 。接下来,mock实际上没有路径依赖类型FruitName的定义,因此无法使用依赖于它的方法签名。

FruitName定义移出FruitImpl时,这正是 工作的原因。它现在独立于模拟而存在,根据它的方法签名然后按预期工作。