Comment simuler une Scala objet singleton?
Je suis en train de simuler une Scala objet singleton. En particulier, j'ai besoin de se moquer de l'objet play.api.libs.ws.WS
utilisé à l'intérieur d'un composant de service (classe sous test).
À l'aide de Mockito ce n'est pas possible, l'exécution du test de l'échec de la façon suivante:
[error] MockitoException: :
[error] Cannot mock/spy class play.api.libs.ws.WS$
[error] Mockito cannot mock/spy following:
[error] - final classes
[error] - anonymous classes
[error] - primitive types (GeolocationSpec.scala:18)
Lecture ici, il semble que Scalamock permet de le faire:
De se moquer autonome objet singleton, l'utilisation
org.scalamock.annotation.mockObject
.
Mon composant de service est quelque chose comme ceci:
trait GeolocationService {
def wsClient = WS
def getPath(origin: Location, destination: Location): Future[Route]
}
class DefaultGeolocationService extends GeolocationService {
val serviceProviderEndpoint = Play.current.configuration.getString("api.directions.endpoint")
override def getPath(origin: Location, destination: Location): Future[Route] = {
val params = Seq(
"origin" -> s"${origin.lat},${origin.lon}",
"destination" -> s"${destination.lat},${destination.lon}"
);
val resp = wsClient.url(serviceProviderEndpoint.get).withQueryString(params: _*).get()
resp.map {
//omitted code
}
}
}
Mon build.sbt a toutes ces dépendances:
[...]
"org.scalatest" %% "scalatest" % "2.2.1",
"org.specs2" %% "specs2" % "2.3.13" % "test",
"org.scalamock" %% "scalamock-specs2-support" % "3.0.1" % "test",
"org.scalamock" %% "scalamock-scalatest-support" % "3.0.1" % "test",
"org.scalamock" %% "scalamock" % "3.0.1",
[...]
mais je ne trouve pas cela: org.scalamock.annotation.mockObject
Probablement cela peut être fait aussi à l'aide de EasyMock et PowerMock, mais je ne trouve aucune Scala exemple de code.
Une idée?
- Se moquer de l'interface qu'il met en œuvre à la place. Prendre que de l'interface comme une dépendance où il est utilisé.
- Comment allez-vous l'appeler? Comme
mock [WS.type]
manière ou d'une autre? - Je seconde @PolymorphicPotato. Il est regrettable que le Jeu du WS est un objet au lieu d'une mise en œuvre d'un générique de trait. Si vous pouvez ajouter un extrait de votre code à l'aide de WS nous pouvons vous guider à dissocier de WS et de le rendre plus facile de se moquer.
- oui, le seul moyen que j'ai trouvé à l'aide de Mockito de se moquer d'un objet sans que des erreurs de compilation est
mock[WS.type]
, mais cela ne fonctionne pas. - Pouvez-vous me dire exactement ce que tu veux dire? L'interface serait se moquer de vous, dans le cas de WS objet singleton?
- Ajouté le code à l'aide de WS.
- Je n'ai pas compris votre question. Voulez-vous vous moquer d'un webservice appel de votre code dans vos tests?
- Oui, je veux bien de se moquer de l'objet
wsClient
à l'intérieur deGeolocationService
retour d'un simulacre deWSRequestHolder
classe lors de laurl(url: String)
méthode est appelée. Le problème est que wsClient est un objet singleton que je ne peux pas refactoriser, il est prévu de Jouer au cadre.
Vous devez vous connecter pour publier un commentaire.
Se moquant de singleton objets à l'aide de ScalaMock 3 est pas possible, mais Paul Boucher s'attend à réintroduire cette fonctionnalité dans ScalaMock 4 (voir http://paulbutcher.com/2014/04/15/scalamock-status-report/)
Ne pas se moquer de l'singleton. Au lieu de WS, faites votre composant de service dépend d'un mince façade de la cacher:
et dans votre test, il suffit de remplacer ws méthode avec un simulacre, qui est maintenant facile de créer:
Je n'aime pas à modifier la conception pour répondre à ce genre de limitation. fondamentalement, ce que je peux obtenir est de tout changement à la conception, puis l'utilisation de la maquette cadre
espère que cela aide.
Pourquoi vous n'utilisez pas le modèle de gâteau?
C'est un peu verbeux, mais il permettra de résoudre votre moqueur problème.
Vous pouvez également utiliser les monades pour ce faire, mais je n'ai jamais mis en œuvre, il est décrit ici:
Scala injection de dépendance: les substituts de paramètres implicites