Reputation: 25050
I try to do unit-test REST communication logic for UWP client. With reference to the answer for System.Web.HttpClient, I found that Windows.Net.HttpClient also accepts an arguement called IHttpFilter
.
So, I try to make custom response with IHttpFilter
but I don't know correct way to make a response.
public class TestFilter : IHttpFilter
{
public IAsyncOperationWithProgress<HttpResponseMessage, HttpProgress> SendRequestAsync(HttpRequestMessage request)
{
if (request.Method == HttpMethod.Get)
{
// response fake response for GET...
}
}
public void Dispose()
{
// do nothing
}
}
And the target method for unit-test is as below.
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";
}
}
Note that It's NOT duplicate question related to System.Web.HttpClient
mocking/faking. What I ask is Windows.Web.HttpClient
specifically. I failed to implement with it.
Note that, Windows.Web.Http.IHttpClient
is internal accessible and HttpClient
is sealed. So hard to do Mock or inherit-and-override it.
Upvotes: 2
Views: 320
Reputation: 61
While I agree with some that there are better ways to test HttpClient calls, I'll answer your question of how to create a "fake" response with an IHttpFilter implementation (System.Runtime.InteropServices.WindowsRuntime is your friend)
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());
}
});
}
}
}
Upvotes: 1