2017-05-19 1 views
0

J'utilise moq pour se moquer d'un emballage j'ai créé pour HttpClient classe:Une bonne façon de se moquer HttpClient et envoyer/recevoir des cookies

public interface IHttpClientWrapper 
{ 
    Task<HttpResponseMessage> PostAsync(Uri uri, 
             HttpContent content, 
             CookieContainer cookies = null); 
} 

et dans ma mise en œuvre de PostAsync « normale », je délègue simplement l'appel à HttpClient

public Task<HttpResponseMessage> PostAsync(Uri uri, HttpContent content, CookieContainer cookies = null) 
{ 
    var client = cookies == null ? new HttpClient() 
     : new HttpClient(new HttpClientHandler { CookieContainer = cookies }); 

    return client.PostAsync(uri, content); 
} 

Ainsi, dans mon application, tout fonctionne bien et je reçois les cookies par le serveur (cookies.Count n'est pas 0)

Pour mon test, j'ai un Mock<IHttpClientWrapper>, et j'ai mis en place sa méthode PostAsync pour retourner un new HttpResponseMessage. J'appelle aussi la méthode HttpResponseMessage.Headers.AddCookies pour ajouter 2 cookies à cette réponse.

Mais quand je l'appelle mon objet moqué d'une manière comme ceci:

/* I setup url and content */ 
var mock = new Mock<IHttpClientHelper>(); 
mock.Setup(/* setup PostAsync to return the response I create */)... 
var cookies = new CookieContainer(); 
var response = await mock.PostAsync(url, content, cookies); 

alors, cookies.Count est toujours 0. Donc, je me demandais ce qui est différent d'appeler le serveur réel? Ai-je besoin d'en-têtes supplémentaires? Comment puis-je définir les cookies ici?

+1

Ce n'est pas un [mcve] qui peut être utilisé pour reproduire le problème. – Nkosi

Répondre

1

CookieContainer passé à PostAsync en tant que paramètre. Le fait que PostAsync ajoute des cookies à CookiesContainer est un effet secondaire de cette méthode, un détail de notammentIHttpClientHelper mise en œuvre. new Mock<IHttpClientHelper> crée une autre implémentation qui n'ajoute pas de cookies.

Donc, si vous voulez ajouter les cookies maquette à un conteneur, il a besoin d'une configuration supplémentaire

mock.Setup(_ => _.PostAsync(It.IsAny<Uri>(), It.IsAny<HttpContent>(), It.IsAny<CookieContainer>())) 
    .Callback<Uri, HttpContent, CookieContainer>((u, c, cookieContainer) => 
    { 
     // Add required cookies here 
     cookieContainer.Add(...); 
    }); 

Callback est une méthode de Mock aux effets secondaires de configuration.

+0

Merci pour votre réponse, je vais le tester et vous le faire savoir :) – Farzad

+0

Juste une question, pouvez-vous s'il vous plaît expliquer pourquoi le 'Callback' fonctionne ici? Je suis nouveau à 'Moq', mais en regardant quelques tutoriels, je pense que' Callback' est appelé quand il y a un deuxième appel à la méthode. Est-ce correct? – Farzad