Aspnetcore.docs: How to inject mock services during integration testing

Created on 19 Jun 2018  Â·  6Comments  Â·  Source: dotnet/AspNetCore.Docs

I can't find where I read this, but I was under the impression that the new ASP.NET Core integration testing mechanism would facilitate injecting mock services by allowing one to replace or overwrite the service registrations in the startup class. Is something along these lines a supported scenario? I am unable to determine from the integration tests docs whether something like this is somehow possible, whether by overriding ConfigureWebHost, or within WithWebHostBuilder. Honestly, not entirely clear what the benefits of using WebApplicationFactory over TestHost are? Plus, unable to locate the docs describing how to use TestHost for integration testing so... any help would be appreciated.


Document Details

⚠ Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.

P2 Source - Docs.ms

Most helpful comment

Overriding services can be achieved calling ConfigureTestServices on the web host builder. There are limitations to this approach, you need to have a startup class and a public void ConfigureServices(IServiceCollection services) method defined on it. If that's the case, you should be golden.

https://github.com/aspnet/Hosting/blob/38f691c09e3aae4f34be139c39ae1fb264803fd0/src/Microsoft.AspNetCore.TestHost/WebHostBuilderExtensions.cs#L15

All 6 comments

TestServer is the in-memory server of TestHost, and WebApplicationFactory uses TestServer. It's not a "one over the other" situation. It might be that it's difficult to connect old concepts and approaches to new the way the topic is written. WebApplicationFactory and the new Microsoft.AspNetCore.Mvc.Testing package make it easier to configure and run tests.

Regarding mock services, let's ask @javiercn to comment on that.

... and @javiercn, do you detect that we need to bridge more between yesteryear testing and testing today in the topic?

Overriding services can be achieved calling ConfigureTestServices on the web host builder. There are limitations to this approach, you need to have a startup class and a public void ConfigureServices(IServiceCollection services) method defined on it. If that's the case, you should be golden.

https://github.com/aspnet/Hosting/blob/38f691c09e3aae4f34be139c39ae1fb264803fd0/src/Microsoft.AspNetCore.TestHost/WebHostBuilderExtensions.cs#L15

@javiercn That will work in my case, so thanks. Curious though, is the reason why that mechanism is not mentioned in the docs because the team would rather people not use it? Or is it going to make it into the docs eventually?

@guardrex I did notice that WebApplicationFactory uses TestServer but that is kinda why I wonder what WebApplicationFactory does that TestServer does not. I think what is not clear is what are those things in WebApplicationFactory which "make it easier to configure and run tests". The best I can gather is it sets the application content root path? I probably don't get the importance of that since I have only built APIs and haven't used Razor/Views/Pages/etc..

I don't mean to critique too much, but perhaps you will find my feedback of some value.

  • I found using the TestServer pretty easy before. It felt like there was less ceremony when using TestServer as opposed to WebApplicationFactory.
  • The integration testing docs are very EF Core focused, and while that can be a big part of ASP.NET Core development, it would probably round out the docs if you showed examples of hooking up/arranging other services/dependencies.

    • How about setting up/arranging an HttpClient that the App itself will use to communicate with an external service (not the HttpClient to communicate with the TestServer). I take it that even with IHttpClientFactory, testing apps with HttpClient still requires faking HttpMessageHandlers (ie, you can't mock/fake HttpClient itself)?

    • And of course, as in my case, just injecting some other service that is just a simple interface/class/etc.

the reason why that mechanism is not mentioned in the docs ... is it going to make it into the docs eventually?

It is something that I'd like to rectify. I think it should be called out. I'll put something together for this asap.

make it easier to configure and run tests

It's in the methods ... see https://docs.microsoft.com/dotnet/api/microsoft.aspnetcore.mvc.testing.webapplicationfactory-1

These are sweet: ConfigureWebHost, CreateClient, WithWebHostBuilder. It requires less boilerplate ... cryptic boilerplate to many ... to get the SUT configured for tests and get tests fired off with a client ... a nicely configurable client. It's very flexible. You can set up multiple factories with custom config for batteries of tests of larger apps. My only concern is the database seeding piece. I find that bit somewhat cryptic at the moment. I wish there was a simpler way to seed the dB for testing.

I found using the TestServer pretty easy before. It felt like there was less ceremony when using TestServer as opposed to WebApplicationFactory.

I take the opposite view, but I'm not a huge integration/functional tester really. I'm more of a unit tester. Someone with much more experience than I may agree with you.

hooking up/arranging other services/dependencies.

The new section I'm thinking about for the topic should help with this part.

setting up/arranging an HttpClient that the App itself will use to communicate with an external service

It's in the sample app. It tests obtaining a GH user profile:

https://github.com/aspnet/Docs/blob/master/aspnetcore/test/integration-tests/samples/2.x/IntegrationTestsSample/tests/RazorPagesProject.Tests/IntegrationTests/BasicTests.cs#L67-L116

https://github.com/aspnet/Docs/blob/master/aspnetcore/test/integration-tests/samples/2.x/IntegrationTestsSample/src/RazorPagesProject/Pages/GithubProfile.cshtml

https://github.com/aspnet/Docs/blob/master/aspnetcore/test/integration-tests/samples/2.x/IntegrationTestsSample/src/RazorPagesProject/Pages/GithubProfile.cshtml.cs

These are sweet: ConfigureWebHost, CreateClient, WithWebHostBuilder. It requires less boilerplate ... cryptic boilerplate to many ... to get the SUT configured for tests and get tests fired off with a client ... a nicely configurable client. It's very flexible. You can set up multiple factories with custom config for batteries of tests of larger apps

Ok, took the time to read the class docs and there is some good info there. I guess I get it, it's just that one does not usually use all of those things at once, but the value would add up over projects or as you said in large projects with varied config needs.

I think you guys more than addressed my question and comments, really appreciate it. I'll leave the issue for you guys to close as it looks like you might be using it to track the updates you mentioned to the docs.

I'll leave the issue for you guys to close as it looks like you might be using it to track the updates you mentioned to the docs.

Yes, that's right. I think your issue with Javier's response has generated an opportunity to make an improvement to the topic. I'll ping u on the PR soon.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

AnthonyMastrean picture AnthonyMastrean  Â·  3Comments

sonichanxiao picture sonichanxiao  Â·  3Comments

Rick-Anderson picture Rick-Anderson  Â·  3Comments

nenmyx picture nenmyx  Â·  3Comments

cocowalla picture cocowalla  Â·  3Comments