如何在Scala中伪造此接口?

时间:2019-03-15 04:58:43

标签: scala unit-testing redis

我正在尝试在Scala中伪造一个接口。在我的规范中,我希望将fakeHmGetResult分配给测试所需的任何内容。


package foo

import com.redis.serialization.{Format, Parse}
import org.scalatest.FunSpec

class SystemUnderTest(fake: ClassToFake) {
  def redisKey(stationId: Any): String = "pdq"

  def systemUnderTest(stationId: Any): Option[StationInfo] = {
    val a = fake.hmget(redisKey(stationId))

    val b = a.get // fails here

    None
  }

}

class TestClass extends FunSpec {

  val fake: ClassToFake = new ActualFake
  val instance = new SystemUnderTest(fake)

  it("should work at runtime") {
    instance.systemUnderTest("123")

    assert(fake.asInstanceOf[ActualFake].getCount === 1)
  }

}

abstract class ClassToFake {
  def hmget[K, V](key: scala.Any, fields: K*)(implicit format: com.redis.serialization.Format, parseV: com.redis.serialization.Parse[V]): scala.Option[_root_.scala.Predef.Map[K, V]]
}

class ActualFake extends ClassToFake {

  var fakeHmgetResult: Map[Any, String] = Map() // compiler doesn't like this...
  var getCount = 0

  override def hmget[K, V](key: Any, fields: K*)(implicit format: Format, parseV: Parse[V]): Option[Map[K, V]] = {
    getCount = getCount + 1
    Some(fakeHmgetResult) 
  }

}

/* Solution code */

class FakeRedisClient extends RedisClient {

  def reset() = {
    setCount = 0
    getCount = 0
    delCount = 0
    keysCount = 0
    fakeHmgetResult = Map()
    fakeKeys = None
  }

  var setCount = 0
  override def hmset(key: Any, map: Iterable[Product2[Any, Any]])(implicit format: Format): Boolean = {
    setCount = setCount + 1
    true
  }

  var getCount = 0

  var fakeHmgetResult: Map[String, String] = Map()

  override def hmget[K, V](key: Any, fields: K*)(implicit format: Format, parseV: Parse[V]): Option[Map[K, V]] = {
    getCount = getCount + 1
    if (fakeHmgetResult.isEmpty) None
    else Some(fakeHmgetResult.asInstanceOf[Map[K,V]])
  }

  var delCount = 0

  override def del(key: Any, keys: Any*)(implicit format: Format): Option[Long] = {
    delCount = delCount + 1
    None
  }

  var keysCount = 0

  var fakeKeys: Option[List[Option[String]]] = None
  override def keys[A](pattern: Any)(implicit format: Format, parse: Parse[A]): Option[List[Option[A]]] = {
    keysCount = keysCount + 1
    fakeKeys.asInstanceOf[Option[List[Option[A]]]]
  }

}

2 个答案:

答案 0 :(得分:1)

在此行

Some(fakeHmgetResult)

您返回了Option[Map[Any, String]],但是在方法签名中您答应了Option[Map[K, V]]

答案 1 :(得分:0)

请参阅问题中的最后一个类...是否需要我所需的API调用技巧。