We are taking the approach of integration testing by running our .NetCore service in Kestrel.
Which has more benefits to us than integration testing at the AppHost
level.
The only issue that we now have is that we want to swap out various dependencies like our persistence store from CosmosDB to an InMemory store, and stub some other things out.
To do that, we simply need to overwrite a couple of the registered services in the running AppHost.Container
.
Given the following code, is there a better option (or syntax) than what we are doing here?
(I feel that this code is violating the principle of not mutating the container after it has been built. It would be better to get into the pipeline sometime after the AppHost.Configure
method has been called instead)
[TestClass, TestCategory("Integration")]
public class CarsApiSpec
{
private const string ServiceUrl = "http://localhost:2000/";
private static IWebHost webHost;
private static IStorage<CarEntity> storage;
[ClassInitialize]
public static void InitializeAllTests(TestContext context)
{
webHost = WebHost.CreateDefaultBuilder(null)
.UseModularStartup<CarsApi.Startup>()
.UseUrls(ServiceUrl)
.UseKestrel()
.ConfigureLogging((ctx, builder) => builder.AddConsole())
.Build();
webHost.Start();
// HACK: Overwrite configured services used only in integration testing
var container = HostContext.Container;
container.AddSingleton<IOtherService, StubOtherService>();
container.AddSingleton<ICarStorage>(c =>
new CarStorage(c.Resolve<IStorage<CarEntity>>()));
storage = CarEntityInMemStorage.Create(container.Resolve<ILogger>(), container.Resolve<IDomainFactory>());
container.AddSingleton(storage);
}
[ClassCleanup]
public static void CleanupAllTests()
{
webHost?.StopAsync().GetAwaiter().GetResult();
}