I am customizing WebApplicationFactory to use Startup, appsettings from original Application project.
Purpose is to create Integration test which points to original application startup. The appsettings json is following for dbcontext:
"ConnectionStrings": {
"DbConnection": "Data Source=.;Initial Catalog = TestDB; Integrated Security=True"
I want to override Services to use inmemory database, from variable below. How would I conduct this?
Custom Web Application Factory:
namespace Integrationtest
{
public class CustomWebApplicationFactory<TStartup> : WebApplicationFactory<TStartup> where TStartup : class
{
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
builder.ConfigureAppConfiguration((hostingContext, configurationBuilder) =>
{
var type = typeof(TStartup);
var path = @"C:\OriginalApplication";
configurationBuilder.AddJsonFile($"{path}\\appsettings.json", optional: true, reloadOnChange: true);
configurationBuilder.AddEnvironmentVariables();
});
}
}
}
Actual Integration Test:
public class DepartmentAppServiceTest : IClassFixture<CustomWebApplicationFactory<OriginalApplication.Startup>>
{
public dbContextTest context;
public CustomWebApplicationFactory<OriginalApplication.Startup> _factory;
public DepartmentAppServiceTest(CustomWebApplicationFactory<OriginalApplication.Startup> factory)
{
_factory = factory;
}
[Fact]
public async Task DepartmentAppTest()
{
using (var scope = _factory.Server.Host.Services.CreateScope())
{
context.Department.Add(new Department { DepartmentId = 2, DepartmentCode = "123", DepartmentName = "ABC" });
context.SaveChanges();
var foo = scope.ServiceProvider.GetRequiredService<IDepartmentAppService>();
var departmentDto = await foo.GetDepartmentById(2);
Assert.Equal("123", departmentDto.DepartmentCode);
}
}
}
I want to override the Services database to use inmemory database, from this variable below. How would I conduct this?
var dbtest = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
var options = new DbContextOptionsBuilder<ApplicationDbContext>()
.UseInMemoryDatabase(databaseName: "TestDB")
.Options;
You can use WebHostBuilder.ConfigureTestServices
to adjust the service configuration that the integration test server uses. That way, you can reconfigure your database context to use a different configuration. This is also covered in the integration testing chapter of the documentation.
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
// …
builder.ConfigureTestServices(services =>
{
// remove the existing context configuration
var descriptor = services.SingleOrDefault(d => d.ServiceType == typeof(DbContextOptions<ApplicationDbContext>));
if (descriptor != null)
services.Remove(descriptor);
services.AddDbContext<ApplicationDbContext>(options =>
options.UseInMemoryDatabase("TestDB"));
});
}
The configuration passed to ConfigureTestServices
will always run after the Startup.ConfigureServices
, so you can use this to override the real services for your integration tests.
For most situations, it will be enough to simply register some other type over the existing registration to make it apply everywhere. Unless you actually retrieve multiple services of a single type (by injecting IEnumerable<T>
somewhere), this will not have a negative effect.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With