2017-09-21 1 views
1

J'utilise Mongodb comme persistance dans mon application et j'écris actuellement un test pour mon code. Mon CUT ressemble à ce qui suitScalamock: se moquer d'une classe de cas générique entraîne une incompatibilité de type

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

Mon modèle est injecté correctement en utilisant des implicits. Je suis moqueur l'appel getCollection qui sur son propre devrait aboutir à une autre maquette, cette fois de type

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

donc ce que je fais est le

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

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

Mais ce résultat dans ce qui suit erreur

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

TResult est le paramètre générique du MongoCollection, qui ressemble à ceci:

case class MongoCollection[TResult](private val wrapped: JMongoCollection[TResult]) { 
.... 
} 

Il semble que le paramètre générique est pas correctement « ajusté » (je ne sais pas comment l'appeler) au document

+1

Salut, on dirait que vous avez rencontré ce bug: https://github.com/paulbutcher/ScalaMock/issues/170. Il est en cours d'élaboration, mais difficile à corriger –

+0

@PhilippM Y at-il une solution de contournement pour cela? –

Répondre

0

spécifiant le paramètre de type initial devrait fonctionner, ou, si votre interface est entièrement abstraite, vous pouvez utiliser une maquette Proxy pour que:

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