purekrome / httpclient.helpers Goto Github PK
View Code? Open in Web Editor NEWSome simple System.Net.Http.HttpClient test helpers
License: MIT License
Some simple System.Net.Http.HttpClient test helpers
License: MIT License
Test application is 2.2 which is now unsupported. Sure, this is a test app only .. but lets keep it up to date.
I'm using the last recent version 5.0 and tried to follow the Wiki, but it seems the FakeHttpMessageHandler ctor has changed and the wiki is not up to date.
From the wiki I should do something like this:
var messageHandler = new FakeHttpMessageHandler(requestUrl, messageResponse);
But there is only one parameter:
I did this in my code and it seems to work:
var messageResponse = FakeHttpMessageHandler.GetStringHttpResponseMessage(responseData, HttpStatusCode.BadRequest);
var fakeMessageHandler = new FakeHttpMessageHandler(new HttpMessageOptions() { HttpResponseMessage = messageResponse });
Is this the right approach?
If we are doing something like a HTTP DELETE where there is no returned body/headers (usually just a status code), then we need a way in our tests to verify the operation was called (since the calling method will return void
).
Suggestion: add WasCalled
property (only get
property) to HttpMessageOptions
, which can then be checked in the test.
e.g
// Arrange.
// ... snip ...
var options = new HttpMessageOptions
{
HttpMethod = HttpMethod.Delete,
RequestUri = "http://api.com/user",
HttpResponseMessage = new HttpResponseMessage(HttpStatusCode.NoContent)
};
var fakeMessageHandler = new FakeHttpMessageHandler(options);
// Act.
var client = new TestClientClient(baseUrl, fakeMessageHandler);
// Act.
await client .DeleteUserAsync(someoperation);
// Assert.
options.WasCalled.ShouldBeTrue();
If a uri has characters that Uri
auto encodes, then the string comparison check fails.
Replace the RequestUri string
with a real Uri
Hi I was wondering if this would work in a dnx project? ASP.NET 5 vnext?
Hi,
I'm using your library to author some tests and I got myself in the situation where my API client is forming a URL by adding many components both in the path and the querystring.
My test is targeting only a subsection of the requested URI and I would like to "test" it. Ideally on the used option.
To make a concrete example
var option = new HttpMessageOptions
{
HttpMethod = HttpMethod.Get,
HttpResponseMessage = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StringContent(JsonConvert.SerializeObject(contact))
},
RequestUri = null
};
var sut = CreateSystemUnderTest(option);
var response = await sut.GetByIdAsync(contactId);
Assert.That(option.InvokedUri, Contains.SubString($"/contacts/v1/contact/vid/{contactId}"));
Right now I am forced to do:
var options = new HttpMessageOptions
{
HttpMethod = HttpMethod.Get,
HttpResponseMessage = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StringContent(JsonConvert.SerializeObject(contact))
},
RequestUri = new Uri($"https://api.hubapi.com/contacts/v1/contact/vid/{contactId}/profile?formSubmissionMode=all&propertyMode=value_and_history&showListMemberships=true")
};
which is really outside of the scope of my unit test.
There's an extra overload for both the ctor injection and Factory to tell the HttpClient
to not internally dispose after the first execution.
Hi, I'm using your latest and greatest library, but after I updated to xUnit2 I'm seeing some weird behaviour. Tests that are touching the HttpClientFactory are failing or succeeding randomly, but I'm not sure if it is a "problem" in your helper library or a test design problem.
For example (without any code chances)
Even the console test runner shows mixed results. After some headaches I found the reason: With xUnit2 tests can now run in parallel:
http://xunit.github.io/docs/running-tests-in-parallel.html
Now pure guessing from me; Because HttpClientFactory is a static thing and it is used in parallel from different tests the tests behave very differently.
Is there a way to inject the HttpClientFactory inside the test class, so each test have their own factory?
My code can be found here:
https://github.com/Code-Inside/Sloader
Hi,
I think I found a bug in the FakeMessageHandler when it compares the incoming HttpContent and the expected ones received from the HttpMessageOptions.
The problem is caused by the fact that your equality check is a reference check.
private HttpMessageOptions GetExpectedOption(HttpMessageOptions option)
{
if (option == null)
{
throw new ArgumentNullException(nameof(option));
}
IEnumerable<HttpMessageOptions> options = _lotsOfOptions.Values;
options = options.Where(x => x.RequestUri == option.RequestUri || x.RequestUri == HttpMessageOptions.NoValue);
options = options.Where(x => (x.HttpMethod == option.HttpMethod || x.HttpMethod == null));
options = options.Where(x => (x.HttpContent == option.HttpContent || x.HttpContent == null));
options = options.Where(x => (x.Headers == null || x.Headers.Count == 0) || (x.Headers != null && HeaderExists(x.Headers, option.Headers)));
return options.SingleOrDefault();
}
If we look at this equivalent version of your code, the error is in the options = options.Where(x => (x.HttpContent == option.HttpContent || x.HttpContent == null));
line.
I reproduced the issue by slightly changing the test. You can check it here: Kralizek@339ae33
Hi!
AutoFixture is a great library for quickly building tests by assemblying test data.
One of the paradigms they support is the usage of test parameters as a way to receive the different parts of the test.
Here is an example
public class SomeHttpService
{
public SomeHttpService(HttpClient client) { }
public Task DoSomethingAsync() { }
}
[TestFixture]
public class SomeHttpServiceTests
{
[Test, MyAutoData]
public void A_test([Frozen] FakeHttpMessageHandler handler, SomeHttpService sut)
{
// customize options
handler.Options.Add(new ...);
sut.DoSomethingAsync();
// verify sent request
Assert.That(handler.Options[0].RequestUri, Is.EqualTo(something)
}
}
Basically with this pattern, there is no direct access to the constructor and the FakeHttpMessageHandler
can only be customized when it gets constructed.
I have a scenario where i am (optionally) passing a header (in my case, the Authorization
header) to a HTTP call.
It would be good to ensure that the call was made with this specific header.
e.g
var httpOptions = new HttpMessageOptions
{
HttpMethod = HttpMethod.Post,
RequestUri = "https://api.com/login",
HttpResponseMessage = new HttpResponseMessage(HttpStatusCode.Created),
Headers = new Dictionary<string,string>
{
{"Authorization", "Bearer xyz"}
}
};
Then in the assertion, NumberOfTimesCalled
should only be incremented for that request if that actual header was passed in HTTP call.
Try a URL like this:
http://www.whatever.com/something?json=%7B%0A%20%20%20%22Ids%22%3A%20%5B16036%2C1%5D%0A%7D
The CreateDictionaryKey
method is erroring, presumably because of the string.Format
not liking the braces...
Is it possible to adjust the nuspec so when a full .NET project references the package then no Core packages would be installed?
Now that HttpClientFactory
was released with .NET Core 2.1, provide some documentation example about how to use this so people can really grok why to use this and how. Also makes it easy and quick to get started.
The current request is not attached to the response returned by FakeHttpHandler
Restoring packages for
Package WorldDomination.HttpClient.Helpers 5.1.0 is not compatible with netcoreapp1.1 (.NETCoreApp,Version=v1.1). Package WorldDomination.HttpClient.Helpers 5.1.0 supports: net45 (.NETFramework,Version=v4.5)
Package Microsoft.Net.Http 2.2.29 is not compatible with netcoreapp1.1 (.NETCoreApp,Version=v1.1). Package Microsoft.Net.Http 2.2.29 supports:
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.