Scalamock:模拟一个通用案例类会导致类型不匹配

时间:2017-09-21 07:47:32

标签: mongodb scala unit-testing scalamock

我在我的应用程序中使用Mongodb作为持久性,我正在为我的代码编写测试。我的CUT看起来如下

    SUNDAY("sunday"),
    MONDAY("monday"),
    TUESDAY("tuesday"),
    UNKNOWN("unknown");

    private final String value;

    DAY(final String value) {
        this.value = value;
    }

    private static final Map<String, DAY> VALUE_TO_TYPE = Stream.of(DAY.values()).collect(Collectors.toMap(d -> d.value, d -> d));

    public String value() {
        return value;
    }

   public static Optional<DAY> fromValue(final String value) {
       return Optional.ofNullable(VALUE_TO_TYPE.get(value));
   }
}

我的模拟通过使用implicits正确注入。我正在嘲笑getCollection调用,它自己应该导致另一个模拟,这次是类型

implicit def storageHandler[M[_]: Monad](
    implicit mongoDatabase: MongoDatabase
) = new Storage.Handler[M] {
    override def store(order: Order): M[Unit] = Monad[M].pure {
      val collection: MongoCollection[Document] = mongoDatabase.getCollection("order")

      val document: Document = Document(order.asJson.toString)

      collection.insertOne(document).subscribe((x: Completed) => ())
   }
}

所以我正在做的是以下

MongoCollection[org.mongodb.scala.bson.collection.immutable.Document]

但是这会导致以下错误

val mongoCollection: MongoCollection[Document] = mock[MongoCollection[Document]]

(mongoDatabase.getCollection[Document] _).expects("order").once().returning(mongoCollection)

TResult是mongoCollection的通用参数,如下所示:

type mismatch;
[error]  found   : com.mongodb.async.client.MongoCollection[TResult]
[error]  required: com.mongodb.async.client.MongoCollection[org.mongodb.scala.bson.collection.immutable.Document]
[error]  val mongoCollection: MongoCollection[Document] = mock[MongoCollection[Document]]

似乎通用参数未正确“调整”(我不知道如何调用它)到Document

1 个答案:

答案 0 :(得分:0)

预先指定类型参数应该有效,或者,如果您的界面是完全抽象的,您可以使用代理模拟:

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

import scala.reflect.ClassTag

class Issue170Test extends FlatSpec with Matchers with MixedMockFactory {
  behavior of "ScalaMock"

  it should "mock this" in {
    class Foo[T: ClassTag]
    "val m = mock[Foo[Nothing]]" should compile // this one fails :(
  }

  trait TotallyAbstract[T] {
    def foo: Int
    def bar: T
  }

  it should "work with this workaround" in {
    class Foo[T: ClassTag]
    abstract class Foo2 extends Foo[Int] // workaround: specify type parameter
    "val m = mock[Foo2]" should compile
    "val m2 = Proxy.mock[TotallyAbstract[Int]]" should compile
  }
}