简体   繁体   中英

How to mock return of None of method which return type is Option[SomeCaseClassDefinedInsideThisClass]

I would expect this test to pass:

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

But it fails with:

[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]               ^  

This works, though:

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

The only difference is that the case class FruitName is defined outside of the class FruitImpl. Why does one version of the code fails and the other doesn't? What should one do to fix the error in the first example?

Without looking at the ScalaMock code, I'd say that the mock is not a true derivation of FruitImpl in the OO sense. Its purpose is to allow method interception, so it only deals with the facade . It follows then that the mock actually has no definition of the path dependent type FruitName , and so cannot work with a method signature that depends on it.

This is precisely why it does work when the FruitName definition is moved out of FruitImpl . It now exists independently of the mock, who's method signatures depending on it then work as expected.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM