-
-
Notifications
You must be signed in to change notification settings - Fork 11
Multiple endpoints
Pure Krome edited this page Apr 3, 2015
·
4 revisions
What: faking a multiple request endpoints
Why: unit testing a service that makes multiple requests to multiple endpoints.
How: Create a fake response for each endpoint the method calls.
NOTE: once an HttpMessageHandler
is executed/used, it gets disposed. Therefore, we setup the message handler to not dispose of, after being used
public class MyService : IMyService
{
private readonly FakeHttpMessageHandler _messageHandler;
public MyService(FakeHttpMessageHandler messageHandler = null)
{
_messageHandler = messageHandler;
}
public async Task<Foo> GetSomeDataAsync()
{
var foo = await GetSomeFooDataAsync();
foo.Baa = await GetSomeBaaDataAsync();
return foo;
}
private async Task<Foo> GetSomeFooDataAsync()
{
HttpResponseMessage message;
string content;
using (var httpClient = _messageHandler == null
? HttpClientFactory.GetHttpClient("someKey", false)
: HttpClientFactory.GetHttpClient(_messageHandler, false)) // <-- Note the `false` property == do NOT dispose.
{
message = await httpClient.GetAsync("http://www.something.com/some/website");
content = await message.Content.ReadAsStringAsync();
}
if (message.StatusCode != HttpStatusCode.OK)
{
// TODO: handle this ru-roh-error.
}
// Assumption: content is in a json format.
return JsonConvert.DeserializeObject<Foo>(content);
}
private async Task<Baa> GetSomeBaaDataAsync()
{
HttpResponseMessage message;
string content;
using (var httpClient = _messageHandler == null
? HttpClientFactory.GetHttpClient("someKey", false)
: HttpClientFactory.GetHttpClient(_messageHandler, false)) // <-- Note the `false` property == do NOT dispose.
{
// NOTE: notice how this request endpoint is different to the one, above?
message = await httpClient.GetAsync("http://www.something.com/another/site");
content = await message.Content.ReadAsStringAsync();
}
if (message.StatusCode != HttpStatusCode.OK)
{
// TODO: handle this ru-roh-error.
}
// Assumption: content is in a json format.
return JsonConvert.DeserializeObject<Baa>(content);
}
}
// ... and a unit test ...
[Fact]
public async Task GivenSomeValidHttpRequests_GetSomeDataAsync_ReturnsAFoo()
{
// Arrange.
const string requestUrl1 = "http://www.something.com/some/website";
const string responseData1 = "I am not some Html.";
// 1. First fake response.
var messageResponse1 = FakeHttpMessageHandler.GetStringHttpResponseMessage(responseData1);
const string requestUrl2 = "http://www.something.com/another/site";
const string responseData2 = "Html, I am not.";
// 2. Second fake response.
var messageResponse2 = FakeHttpMessageHandler.GetStringHttpResponseMessage(responseData2);
var messageResponses = new Dictionary<string, HttpResponseMessage>
{
{requestUrl1, messageResponse1},
{requestUrl2, messageResponse2}
};
// 3. Wire up the Factory to return these fake responses if those urls are attempted.
var messageHandler = new FakeHttpMessageHandler(messageResponses);
var myService = new MyService(messageHandler);
// Act.
// NOTE: network traffic will not leave your computer because you've faked the response, above.
var result = myService.GetSomeDataAsync();
// Assert.
result.Id.ShouldBe(69);
}
- The Basics
- Common 'Happy Path' usages
- Common 'Sad Panda' usages
- Other interesting stuff