I’ve been banging my head against the wall trying to figure out how to component test my Web API. Once upon time this used to be a fairly simple process using TestServer
and having a testable Startup
class but this seems to have changed.
I have tried using:
var foo = new WebApplicationFactory<Startup>();
var bar = foo.CreateClient();
var client = await bar.GetAsync($"/price/ada/adad/asas/v1/prices?itemNumber=123");
The problem I get here is it just hangs on creating the client with no feedback to whats actually happening.
So I went down the route of using TestServer
where it seems to be much better however, it seems for it to work I need to place my TestStartup
class in the same assembly as Startup
? I don’t remember having to do this, is it possible to have the TestStartup
class live in my Test library and act the same way?
For example, this is my setup
public class Startup
{
private readonly IConfiguration _configuration;
public Startup(IConfiguration configuration)
{
_configuration = configuration;
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILogger<Startup> logger)
{
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
public void ConfigureServices(IServiceCollection services)
{
ConfigureExternalDependencies(services);
services.AddControllers();
services.AddRouting();
}
protected virtual void ConfigureExternalDependencies(IServiceCollection services)
{
// .. override external I/O stuff
}
}
TestStartup looks like this:
public class TestStartup : Startup
{
public TestStartup() : base(BuildConfiguration())
{
}
protected override void ConfigureExternalDependencies(IServiceCollection services)
{
services.AddTransient<IGetMultiplePricesQuery>(_ => Substitute.For<IGetMultiplePricesQuery>());
}
private static IConfiguration BuildConfiguration()
{
return new ConfigurationBuilder()
.AddInMemoryCollection()
.Build();
}
}
When I use TestServer
usage is as follows:
var webHostBuilder = new WebHostBuilder().UseStartup<TestStartup>();
_server = new TestServer(webHostBuilder);
var client = _server.CreateClient();
_httpResponse = await client.GetAsync($"/price/ada/adad/asas/v1/prices?itemNumber=123");
This works but I would like my TestStartup to not live in the production code space. Am I missing something here?