Skip to content

Commit

Permalink
Update documentation (#10)
Browse files Browse the repository at this point in the history
* 💄 Cleaned up the ReadMe.md.
* Don't publish a -pre nuget if the repo is tagged.
* 2x Unit Tests for 'Sad Panda' scenario's.
  • Loading branch information
PureKrome authored Nov 10, 2016
1 parent 4c504e3 commit e7413d3
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 86 deletions.
74 changes: 11 additions & 63 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#HttpClient.Helpers
# HttpClient.Helpers

| Stage | CI | NuGet |
|-------------|----|-------|
Expand All @@ -11,6 +11,12 @@ Code that uses `System.Net.Http.HttpClient` will attempt to actually call/hit th

To prevent this from happening in a *unit* test, some simple helpers are provided in this code library.

## Key Points
- Use Dependency Injection to hijack your request (this library makes it _supa dupa easy_ to do this)
- Works with GET/POST/etc.
- Can provide wildcards (i.e. I don't care about the Request endpoint or the request HTTP Method, etc)
- Can provide multiple endpoints and see handle what is returned based on the particular request.
- Can be used to test network errors during transmission. i.e. can test when the HttpClient throws an exception because of .. well ... :boom:
-----

## Installation
Expand All @@ -22,70 +28,12 @@ CLI: `install-package WorldDomination.HttpClient.Helpers`


## Sample Code
This sample uses the Factory and a Key. The other option is to use [constructor injection with a `FakeHttpMessageHandler` parameter](https://github.com/PureKrome/HttpClient.Helpers/wiki/Constructor-Injection).

```C#
public class MyService : IMyService
{
public const string SomeKey = "pewpew";

public async Task<Foo> GetSomeDataAsync()
{
HttpResponseMessage message;
string content;

// ** NOTE: We use the HttpClientFactory, making it easy to unit test this code.
using (var httpClient = HttpClientFactory.GetHttpClient(SomeKey))
{
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.
var foo = JsonConvert.Deserialize<Foo>(content);

return foo;
}
}

// ... and a unit test ...
[Fact]
public async Task GivenAValidHttpRequest_GetSomeDataAsync_ReturnsAFoo()
{
// Arrange.
const string requestUrl = "http://www.something.com/some/website";
const string responseData = "I am not some Html.";
var myService = new MyService();

// 1. Fake response.
var messageResponse = FakeHttpMessageHandler.GetStringHttpResponseMessage(responseData);

// 2. Fake handler that says: for this Url, return this (fake) response.
var messageHandler = new FakeHttpMessageHandler(requestUrl, messageResponse);

// 3. Add this message handler to the factory, for the specific key.
HttpClientFactory.AddMessageHandler(messageHandler, MyService.SomeKey);

// 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);
}
```

There's [plenty more examples](https://github.com/PureKrome/HttpClient.Helpers/wiki) about to wire up:

- [Multiple endpoints](https://github.com/PureKrome/HttpClient.Helpers/wiki/Multiple-endpoints) at once
- [Wildcard endpoints](https://github.com/PureKrome/HttpClient.Helpers/wiki/Wildcard-endpoints)
- [Throwing exceptions](https://github.com/PureKrome/HttpClient.Helpers/wiki/Faking-an-Exception) and handling it
- [A really simple example](https://github.com/PureKrome/HttpClient.Helpers/wiki/Constructor-Injection)
- [Multiple endpoints](https://github.com/PureKrome/HttpClient.Helpers/wiki/Multiple-endpoints) at once
- [Wildcard endpoints](https://github.com/PureKrome/HttpClient.Helpers/wiki/Wildcard-endpoints)
- [Throwing exceptions](https://github.com/PureKrome/HttpClient.Helpers/wiki/Faking-an-Exception) and handling it

For all the samples, please [check out the Wiki page: Helper Examples](https://github.com/PureKrome/HttpClient.Helpers/wiki)

Expand Down
2 changes: 2 additions & 0 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ deploy:
secure: 36bcjhroAjclbHs7e7oh6Hsv4lokADI6xaQcCYZmux2Sdu/IIoktFc9ORK3DTdKo
skip_symbols: true
artifact: /.*\.nupkg/
on:
appveyor_repo_tag: false
- provider: NuGet
api_key:
secure: jfcUvHZhgnUboplqTBDWr8mG5PIlrgBv5TA2fhhop4ZSiDxskyy+RtYyeHoduJFR
Expand Down
85 changes: 62 additions & 23 deletions tests/HttpClient.Helpers.Tests/GetAsyncTests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
Expand Down Expand Up @@ -138,28 +139,6 @@ await DoGetAsync(RequestUri,
fakeHttpMessageHandler);
}

private static async Task DoGetAsync(string requestUri,
string expectedResponseContent,
FakeHttpMessageHandler fakeHttpMessageHandler)
{
requestUri.ShouldNotBeNullOrWhiteSpace();
expectedResponseContent.ShouldNotBeNullOrWhiteSpace();
fakeHttpMessageHandler.ShouldNotBeNull();

HttpResponseMessage message;
string content;
using (var httpClient = new System.Net.Http.HttpClient(fakeHttpMessageHandler))
{
// Act.
message = await httpClient.GetAsync(requestUri);
content = await message.Content.ReadAsStringAsync();
}

// Assert.
message.StatusCode.ShouldBe(HttpStatusCode.OK);
content.ShouldBe(expectedResponseContent);
}

[Fact]
public async Task GivenAnHttpResponseMessage_GetAsync_ReturnsAFakeResponse()
{
Expand Down Expand Up @@ -199,5 +178,65 @@ await DoGetAsync(RequestUri,
ExpectedContent,
fakeHttpMessageHandler);
}

[Fact]
public async Task GivenAnUnauthorisedStatusCodeResponse_GetAsync_ReturnsAFakeResponseWithAnUnauthorisedStatusCode()
{
// Arrange.
var messageResponse = FakeHttpMessageHandler.GetStringHttpResponseMessage("pew pew", HttpStatusCode.Unauthorized);
var messageHandler = new FakeHttpMessageHandler(RequestUri, messageResponse);

HttpResponseMessage message;
using (var httpClient = new System.Net.Http.HttpClient(messageHandler))
{
// Act.
message = await httpClient.GetAsync(RequestUri);
}

// Assert.
message.StatusCode.ShouldBe(HttpStatusCode.Unauthorized);
}

[Fact]
public async Task GivenAValidHttpRequest_GetSomeDataAsync_ReturnsAFoo()
{
// Arrange.
const string errorMessage = "Oh man - something bad happened.";
var expectedException = new HttpRequestException(errorMessage);
var messageHandler = new FakeHttpMessageHandler(expectedException);

Exception exception;
using (var httpClient = new System.Net.Http.HttpClient(messageHandler))
{
// Act.
// NOTE: network traffic will not leave your computer because you've faked the response, above.
exception = await Should.ThrowAsync<HttpRequestException>(async () => await httpClient.GetAsync(RequestUri));
}

// Assert.
exception.Message.ShouldBe(errorMessage);
}

private static async Task DoGetAsync(string requestUri,
string expectedResponseContent,
FakeHttpMessageHandler fakeHttpMessageHandler)
{
requestUri.ShouldNotBeNullOrWhiteSpace();
expectedResponseContent.ShouldNotBeNullOrWhiteSpace();
fakeHttpMessageHandler.ShouldNotBeNull();

HttpResponseMessage message;
string content;
using (var httpClient = new System.Net.Http.HttpClient(fakeHttpMessageHandler))
{
// Act.
message = await httpClient.GetAsync(requestUri);
content = await message.Content.ReadAsStringAsync();
}

// Assert.
message.StatusCode.ShouldBe(HttpStatusCode.OK);
content.ShouldBe(expectedResponseContent);
}
}
}

0 comments on commit e7413d3

Please sign in to comment.