-
Notifications
You must be signed in to change notification settings - Fork 5.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Testability Issue #10309
Comments
I second this, while being able to control the life-time of the handlers is interesting, injecting the |
If you are injecting concrete implementation in the constructor, the entire service I can't test!. Please give a solution to it. We have segregated all the the http call logic to a separate call, that will be injected to other services. Thus reducing the un-testable code to minimum. But there should be a better way to do it. |
I think if you want to test your class that takes the httpclient, then just create an instance of httpclient using the overloaded constructor and add your own faked HttpMessageHandler like you would in any other case. I think where I get a little confused if I wanted to test Polly in this case. The polly extensions mentioned in the next section are put together as part of the factory operation, but how can I do a setup to simulate the error to test that my httpclient is using polly policies and doing things like using fallbacks, and so on? |
Hi, thanks for your feedback. Regrettably (or not) there's no You can use the option that @jstafford5380 mentions, however it might be a bit cumbersome to setup. I've used another approach that I've found to be quite simple to mock and, IMHO, much more clear than using Just so you might give it a try:
This way, you'd inject The services.AddHttpClient<PaymentProcessClient>(client =>
{
client.BaseAddress = new Uri(Configuration["App:BaseUrl"]);
}); But now you want/have to test
About the testing of Polly strategies, what I've thought about, but haven't actually implemented yet (I might in a few days), is to use integration testing, deploy the services to Docker containers and control the connection/reconnection to the "remote" services being tested by accessing the local Docker REST API endpoints for controlling the network connections. Hope this helps. |
Hey @jstafford5380, just learned about Simmy a Polly companion to test for resiliency. This looks quite interesting! Although, at least for some initial testing, it's perhaps better to have some "deterministic" failures. Cheers. |
I am using RichardSzalay.MockHttp for this.
... |
At the time of my suggestion, I hadn't been using https://www.nuget.org/packages/Microsoft.Extensions.Http.Polly/ Under the hood, it basically does what I was recommending which was adding a custom handler to the client. For the testing, the nice thing about what I was recommending is that you can setup your fake handler to behave exactly how you need it to behave in order to setup your test. What I ended up doing is coding my service classes/facades to take // my fake handler lets me set the response status code and optional response body
// it counts tracks calls to `Send(...)` but make it do whatever you need
var fakeHandler = new MyFakedHandler(200, someTestResponseBody);
var client = new HttpClient(fakeHandler);
var service = new MyService(client);
// assume this service facade fails if 200 is not returned
var result = service.DoThing(args);
// assert whatever makes sense
Assert.Equal(1, fakeHandler.CallCount);
Assert.NotNull(result); |
Thanks @GitMarJansen, @jstafford5380, I find both approaches quite interesting! 👍 I'm adding a link from eShopOnContainers wiki, because this is an interesting discussion to keep referenced. 😊 I think the original question has been handled so I'm closing this issue now, but feel free to comment, will reopen if needed. |
How would you write unit tests for a class that has HttpClient injected in its constructor (such as the CatalogService example above)? I would prefer if there were an interface (something called IHttpClient, or maybe IHttpMessageInvoker) that could be injected instead. Then providing a mock implementation for a unit test would be more straightforward.
Document Details
⚠ Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.
The text was updated successfully, but these errors were encountered: