2016-04-21 1 views
1

Ich versuche Unit-Test REST-Kommunikationslogik für UWP-Client zu tun. Mit Bezug auf the answer for System.Web.HttpClient habe ich festgestellt, dass Windows.Net.HttpClient auch ein Argument namens IHttpFilter akzeptiert.UWP Windows.Web.HttpClient gefälscht für Komponententest

Also, ich versuche, benutzerdefinierte Antwort mit IHttpFilter zu machen, aber ich weiß nicht, richtige Art und Weise eine Antwort zu machen.

Und die Zielmethode für Unit-Test ist wie folgt.

public async Task<string> PostResult(HttpClient httpClient, string username) 
    { 
     var json = new JsonObject 
     { 
      {"Username", 
       JsonValue.CreateStringValue(string.IsNullOrEmpty(username) ? CommonKey.UnAuthorizedUserPartitionKey : username) 
      }, 
     }; 

     var content = new HttpStringContent(json.Stringify()); 
     content.Headers.ContentType = new HttpMediaTypeHeaderValue("application/json"); 

     // I want to make below line testable... 
     var response = await httpClient.PostAsync(new Uri(Common.ProcessUrl), content); 
     try 
     { 
      response.EnsureSuccessStatusCode(); 
      return null; 
     } 
     catch (Exception exception) 
     { 
      return exception.Message ?? "EMPTY ERROR MESSAGE"; 
     } 
    } 

Hinweis, dass es nicht Frage zu System.Web.HttpClient spöttischen/Fälschen Zusammenhang dupliziert. Was ich frage ist Windows.Web.HttpClient speziell. Ich scheiterte an implementieren damit.

Beachten Sie, dass Windows.Web.Http.IHttpClient ist interne zugänglich und HttpClient ist versiegelt. So schwer, Mock zu machen oder zu erben und zu überschreiben.

+1

Warum nicht den ganzen direkten Aufruf von 'HttpClient' weglassen und die benötigte Funktionalität hinter einer Abstraktion aufdecken. Du gibst dir selbst unnötige Arbeit (IMHO). – Nkosi

+0

rechts. Ich bin ein wenig verwirrt :(Ich füge die Zielmethode zum Testen an. – Youngjae

+0

Mögliches Duplikat von [Mocking HttpClient in Unit Tests] (http://stackoverflow.com/questions/36425008/mocking-httpclient-in-unit-tests) – Nkosi

Antwort

0

Während ich einigen zustimme, dass es bessere Möglichkeiten gibt, HttpClient-Aufrufe zu testen, beantworte ich Ihre Frage, wie Sie eine "falsche" Antwort mit einer IHttpFilter-Implementierung erstellen (System.Runtime.InteropServices.WindowsRuntime ist Ihr Freund)

using System; 
using System.Collections.Generic; 
using System.Runtime.InteropServices.WindowsRuntime; 
using System.Threading; 
using System.Threading.Tasks; 
using Windows.Foundation; 
using Windows.Web.Http; 
using Windows.Web.Http.Filters; 

namespace Project.UnitTesting 
{ 
    public class FakeResponseFilter : IHttpFilter 
    { 
     private readonly Dictionary<Uri, HttpResponseMessage> _fakeResponses = new Dictionary<Uri, HttpResponseMessage>(); 

     public void AddFakeResponse(Uri uri, HttpResponseMessage responseMessage) 
     { 
      _fakeResponses.Add(uri, responseMessage); 
     } 

     public void Dispose() 
     { 
      // Nothing to dispose 
     } 

     public IAsyncOperationWithProgress<HttpResponseMessage, HttpProgress> SendRequestAsync(HttpRequestMessage request) 
     { 
      if (_fakeResponses.ContainsKey(request.RequestUri)) 
      { 
       var fakeResponse = _fakeResponses[request.RequestUri]; 
       return DownloadStringAsync(fakeResponse); 
      } 

      // Alternatively, you might want to throw here if a request comes 
      // in that is not in the _fakeResponses dictionary. 
      return DownloadStringAsync(new HttpResponseMessage(HttpStatusCode.NotFound) { RequestMessage = request }); 
     } 

     private IAsyncOperationWithProgress<HttpResponseMessage, HttpProgress> DownloadStringAsync(HttpResponseMessage message) 
     { 
      return AsyncInfo.Run(delegate (CancellationToken cancellationToken, IProgress<HttpProgress> progress) 
      { 
       progress.Report(new HttpProgress()); 

       try 
       { 
        return Task.FromResult(message); 
       } 
       finally 
       { 
        progress.Report(new HttpProgress()); 
       } 

      }); 
     } 
    } 
}