2009-04-30 14 views
1

J'implémente un client qui consomme un service web. Je veux réduire les dépendances et j'ai décidé de me moquer du webservice.
J'utilise mockito, il a l'avantage par rapport à EasyMock de pouvoir se moquer des classes, pas seulement des interfaces. Mais ce n'est pas le point.Stratégies pour se moquer d'un webservice

Dans mon test, j'ai ce code:

// Mock the required objects 
Document mDocument = mock(Document.class); 
Element mRootElement = mock(Element.class); 
Element mGeonameElement = mock(Element.class); 
Element mLatElement = mock(Element.class); 
Element mLonElement = mock(Element.class); 

// record their behavior 
when(mDocument.getRootElement()).thenReturn(mRootElement); 
when(mRootElement.getChild("geoname")).thenReturn(mGeonameElement); 
when(mGeonameElement.getChild("lat")).thenReturn(mLatElement); 
when(mGeonameElement.getChild("lon")).thenReturn(mLonElement); 
// A_LOCATION_BEAN is a simple pojo for lat & lon, don't care about it! 
when(mLatElement.getText()).thenReturn(
    Float.toString(A_LOCATION_BEAN.getLat())); 
when(mLonElement.getText()).thenReturn(
    Float.toString(A_LOCATION_BEAN.getLon())); 

// let it work! 
GeoLocationFetcher geoLocationFetcher = GeoLocationFetcher 
    .getInstance(); 
LocationBean locationBean = geoLocationFetcher 
    .extractGeoLocationFromXml(mDocument); 

// verify their behavior 
verify(mDocument).getRootElement(); 
verify(mRootElement).getChild("geoname"); 
verify(mGeonameElement).getChild("lat"); 
verify(mGeonameElement).getChild("lon"); 
verify(mLatElement).getText(); 
verify(mLonElement).getText(); 

assertEquals(A_LOCATION_BEAN, locationBean); 

Ce que mon code montre est que je "micro-test" de l'objet consommation. C'est comme si j'allais implémenter mon code productif dans mon test. Un exemple pour le résultat xml est London on GeoNames. À mon avis, c'est beaucoup trop granuleux.

Mais comment puis-je me moquer d'un webservice sans donner aucun résultat? Dois-je laisser l'objet simulé retourner un fichier XML?

Il ne s'agit pas du code, mais de l'approche .

J'utilise 4.x JUnit et Mockito 1.7

Répondre

1

vous voulez vraiment être moqueur les résultats renvoyés par le webservice au code qui utilisera le résultat. Dans votre exemple de code ci-dessus, vous semblez vous moquer de mDocument, mais vous voulez vraiment transmettre une instance de mDocument qui a été retournée depuis une instance mockée de votre service web et affirmer que locationBean retourné par geoLocationFetcher correspond à la valeur de A_LOCATION_BEAN.

+1

Merci, je me suis votre point. Alors, comment voulez-vous "se moquer d'un webservice"? – guerda

+1

Habituellement, je déclarais une interface et créer un wrapper webservice qui implémente l'interface et instancie le webservice – lomaxx

+0

Donc, vous venez de vérifier le résultat, votre client webservice revient? – guerda

2

Je pense que le vrai problème ici est que vous avez un singleton qui appelle et crée le service Web, il est donc difficile d'insérer un simulacre.

Vous devrez peut-être ajouter (éventuellement au niveau du package) un accès à la classe singleton. Par exemple, si le constructeur ressemble à

private GeoLocationFactory(WebService service) { 
    ... 
} 

vous pouvez rendre le niveau du constructeur et en créer un avec un service Web simulé.

Vous pouvez également définir le service Web en ajoutant une méthode setter, bien que je n'aime pas les singletons mutables. Aussi, dans ce cas, vous devez vous rappeler de désactiver le service Web par la suite.

Si le service Web est créé dans une méthode, vous devrez peut-être rendre GeoLocationFactory extensible pour remplacer le service fictif.

Vous pouvez également regarder dans supprimer le singleton lui-même. Il y a des articles en ligne et probablement ici sur la façon de le faire.

1

L'option la plus simple serait de se moquer du client WebService,

when(geoLocationFetcher.extractGeoLocationFromXml(anyString())) 
    .thenReturn("<location/>"); 

Vous pouvez modifier le code pour lire le xml de réponse du système de fichiers.

Exemple de code se trouve ici: Mocking .NET WebServices with Mockito