You should use TestServer
, which bootstraps a complete test environment (optionally using a different startup class or environment variable, where you can replace data store with an in-memory store).
The ASP.NET Core documentation covers this case quite well.
var server = new TestServer(new WebHostBuilder()
.UseStartup<Startup>()
// this would cause it to use StartupIntegrationTest or ConfigureServicesIntegrationTest / ConfigureIntegrationTest methods (if existing)
// rather than Startup, ConfigureServices and Configure
.UseEnvironment("IntegrationTest"));
In these alternative/environment-dependent methods you can put your integration test specific replacements/DI configuration.
Second, controllers (and tag helpers and view components) are not registered with the DI system by default. The controller factories will resolve the types. If you want that the controllers to get resolved via built-in or 3rd party IoC containers, you have to tell ASP.NET Core to register them explicitly (see this related question).
Here is an example:
services
.AddMvc()
.AddControllersAsServices()
.AddViewComponentsAsServices()
.AddTagHelpersAsServices();
I would recommend you to use the first approach, as it's more consistent and exactly the reason the Startup
class with environment support is there.
Update
Important addition. If you use the TestServer
, you can also access its DI Container (IServiceProvider
instance).
var server = new TestServer(new WebHostBuilder()
.UseStartup<Startup>()
.UseEnvironment("IntegrationTest"));
var controller = server.Host.Services.GetService<MyController>();