2009-07-13 5 views
2

Aujourd'hui, j'ai rencontré un problème TDD très difficile. J'ai besoin d'interagir avec un serveur via HTTP POST. J'ai trouvé le Apache Commons HttpClient, qui fait ce dont j'ai besoin.Tests unitaires avec plusieurs collaborateurs

Cependant, je me retrouve avec un tas d'objets collaborateurs de Apache Commons:

public void postMessage(String url, String message) throws Exception { 

    PostMethod post = new PostMethod(url); 
    RequestEntity entity = new StringRequestEntity(message, 
             "text/xml; charset=ISO-8859-1"); 
    post.setRequestEntity(entity); 
    HttpClient httpclient = new HttpClient(); 
    try { 
     int result = httpclient.executeMethod(post); 

     System.out.println("Response status code: " + result); 
     System.out.println("Response body: "); 
     System.out.println(post.getResponseBodyAsString()); 
    } finally { 
     post.releaseConnection(); 
    } 
} 

J'ai un objet PostMethod, un objet RequestEntity et un objet HttpClient. Je me sens relativement à l'aise en passant par l'injection d'ala dépendance HttpClient, mais que dois-je faire des autres collaborateurs?

Je pourrais créer un tas de méthodes d'usine (ou une classe d'usine) pour créer les collaborateurs, mais j'ai un peu peur que je me moque trop.

Suivi

Merci pour les réponses! Ma question qui reste est une méthode comme ceci:

public String postMessage(String url, String message) throws Exception { 

    PostMethod post = new PostMethod(url); 
    RequestEntity entity = new StringRequestEntity(message, 
             "text/xml; charset=ISO-8859-1"); 
    post.setRequestEntity(entity); 
    HttpClient httpclient = new HttpClient(); 
    httpclient.executeMethod(post); 
    return post.getResponseBodyAsString(); 
} 

Comment puis-je vérifier à juste titre que la valeur retournée est de post.getResponseBodyAsString()? Aurais-je besoin de simuler post ainsi que client?

Répondre

4

Réponse courte: faux HttpClient, ne pas se moquer de PostMethod ou RequestEntity.

Bien sûr, il s'agit d'un appel de jugement, mais je suggère de commencer par se moquer des choses qui ont vraiment besoin d'être moqué: HttpClient. PostMethod et RequestEntity sont pile-local, rapide et déterministe, je les laisserais comme ils sont, vous pouvez toujours les railler plus tard si nécessaire. Comme votre code est maintenant, en se moquant de PostMethod et de RequestEntity vous compliquez votre API, compliquez le code qui utilise votre API, et exposez les détails de votre implémentation. Au fur et à mesure que votre code évolue, vous aurez une meilleure idée de ce qui doit être raillé, pas besoin d'essayer de prédire l'avenir maintenant.

Cela pourrait être utile:

http://www.testingreflections.com/node/view/7417

3

La réponse de zielaj est son, mais vous pouvez aussi créer un PostMethodFactory avec la signature suivante:

PostMethod getInstance(String url, String message, String contentType); 

... puis utilisez DI pour injecter à la fois et le HttpClient. Ensuite, vous auriez seulement deux choses à se moquer.

Le PostMethodFactory pourrait être mis en œuvre ainsi:

public PostMethod getInstance(String url, String content, String contentType, String charset) { 
    PostMethod post = new PostMethod(url); 
    RequestEntity entity = new StringRequestEntity(message, contentType, charset); 
    post.setRequestEntity(entity); 
    return post; 
}