From e7413d35fa757b7c7ee440fcaf33eb5c3ca51bf7 Mon Sep 17 00:00:00 2001 From: Pure Krome Date: Thu, 10 Nov 2016 23:38:34 +1100 Subject: [PATCH] Update documentation (#10) * :lipstick: Cleaned up the ReadMe.md. * Don't publish a -pre nuget if the repo is tagged. * 2x Unit Tests for 'Sad Panda' scenario's. --- README.md | 74 +++------------- appveyor.yml | 2 + .../HttpClient.Helpers.Tests/GetAsyncTests.cs | 85 ++++++++++++++----- 3 files changed, 75 insertions(+), 86 deletions(-) diff --git a/README.md b/README.md index 8adeb17..f9b0abe 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -#HttpClient.Helpers +# HttpClient.Helpers | Stage | CI | NuGet | |-------------|----|-------| @@ -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 @@ -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 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(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) diff --git a/appveyor.yml b/appveyor.yml index d7d90c7..4f8250b 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -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 diff --git a/tests/HttpClient.Helpers.Tests/GetAsyncTests.cs b/tests/HttpClient.Helpers.Tests/GetAsyncTests.cs index c4bcec3..009600c 100644 --- a/tests/HttpClient.Helpers.Tests/GetAsyncTests.cs +++ b/tests/HttpClient.Helpers.Tests/GetAsyncTests.cs @@ -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; @@ -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() { @@ -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(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); + } } } \ No newline at end of file