2015-09-23 13 views
5

Non esiste un modo semplice per ottenere un accesso a nell'oggetto response eseguendo test di integrazione con AspNet.TestHost.TestServer. I cookie devono essere impostati dall'azione del controller. Qual è il modo migliore per farlo?Accesso ai cookie all'interno del test unitario nel contesto AspNet.TestHost.TestServer su ASP.NET 5/MVC 6

  var client = TestServer.Create(app => 
      { 
       app.UseMvc(routes => 
         routes.MapRoute("default", "{controller}/{action}/{id?}")); 
       app.UseIdentity(); 
      }).CreateClient(); 

      var request = new HttpRequestMessage(HttpMethod.Get, "account/login"); 
      var response = await client.SendAsync(request); 

      // how to get an access to cookie container ????????? 
      // response.Cookies prop doesn't exist 
      Assert.NotEmpty(response.Cookies["auth"]); 

soluzione che vedo è quello di estendere istanza del TestServer, tornare istanza di una classe CustomClientHandler : ClientHandler e sovrascrivere l'intero processo di invio di una richiesta in tale gestore, ma ha bisogno letteralmente di cambiare ogni logica, tranne relativamente piccolo codice del TestServer.

Qualche suggerimento migliore su come implementare un accesso ai cookie in una risposta?

risposta

6

I cookie sono solo intestazioni. Ecco un esempio di prendere un cookie da una risposta e aggiungerlo alla successiva richiesta: https://github.com/aspnet/Mvc/blob/538cd9c19121f8d3171cbfddd5d842cbb756df3e/test/Microsoft.AspNet.Mvc.FunctionalTests/TempDataTest.cs#L201-L202

+1

Un collegamento a una potenziale soluzione è sempre il benvenuto, ma per favore [aggiungi contesto intorno al link] (// meta.stackoverflow.com/a/8259) così i tuoi utenti avranno un'idea di cosa sia e perché è lì . ** Cita sempre la parte più rilevante di un link importante, nel caso in cui il sito target sia irraggiungibile o sia permanentemente offline. ** Considera che essere _barely più di un link a un sito esterno_ è una possibile ragione per [Perché e come vengono eliminate alcune risposte?] (// stackoverflow.com/help/deleted-answers). – kayess

+0

Sentiti libero di ampliare la risposta, ho avuto solo il tempo di indirizzarli nella giusta direzione. Sembra anche che abbia aiutato. – Tratcher

0

Ho implementato HttpMessageHandler personalizzato che tiene traccia dei cookie.

Usa la riflessione per richiamare l'attuale gestore e legge/imposta le intestazioni dei cookie.

class TestMessageHandler : HttpMessageHandler 
{ 
    delegate Task<HttpResponseMessage> HandlerSendAsync(HttpRequestMessage message, CancellationToken token); 

    private readonly HandlerSendAsync nextDelegate; 
    private readonly CookieContainer cookies = new System.Net.CookieContainer(); 

    public TestMessageHandler(HttpMessageHandler next) 
    { 
     if(next == null) throw new ArgumentNullException(nameof(next)); 

     nextDelegate = (HandlerSendAsync) 
          next.GetType() 
           .GetTypeInfo() 
           .GetMethod("SendAsync", BindingFlags.NonPublic | BindingFlags.Instance) 
           .CreateDelegate(typeof(HandlerSendAsync), next); 
    } 

    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) 
    { 
     request.Headers.Add("Cookie", cookies.GetCookieHeader(request.RequestUri)); 

     var resp = await nextDelegate(request, cancellationToken).ConfigureAwait(false); 

     if (resp.Headers.TryGetValues("Set-Cookie", out var newCookies)) 
     { 
      foreach (var item in SetCookieHeaderValue.ParseList(newCookies.ToList())) 
      { 
       cookies.Add(request.RequestUri, new Cookie(item.Name, item.Value, item.Path)); 
      } 
     } 

     return resp; 
    } 
} 

E poi si crea il HttpClient in questo modo:

var httpClient = new HttpClient(
        new TestMessageHandler(
         server.CreateHandler())); 

TestMessageHandler ora si prende cura dei tracking cookie.