Net Core:使用 InMemory Database 覆盖 WebApplicationFactory Servi



我正在自定义WebApplicationFactory以使用原始应用程序项目中的启动,应用程序设置。

目的是创建指向原始应用程序启动的集成测试。对于数据库上下文,应用程序设置 json 如下:

  "ConnectionStrings": {
    "DbConnection": "Data Source=.;Initial Catalog = TestDB; Integrated Security=True"

我想从下面的变量中覆盖服务以使用内存数据库。我将如何进行此操作?

自定义 Web 应用程序工厂:

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();
            });
        }
    }
}

实际集成测试:

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);
        }
    }
}

我想从下面的这个变量覆盖服务数据库以使用内存数据库。我将如何进行此操作?

           var dbtest = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
           var options = new DbContextOptionsBuilder<ApplicationDbContext>()
            .UseInMemoryDatabase(databaseName: "TestDB")
            .Options;

可以使用WebHostBuilder.ConfigureTestServices来调整集成测试服务器使用的服务配置。这样,您就可以重新配置数据库上下文以使用其他配置。文档的集成测试一章也介绍了这一点。

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"));
    });
}

传递给ConfigureTestServices的配置将始终Startup.ConfigureServices之后运行,因此您可以使用它来覆盖集成测试的实际服务。

在大多数情况下,只需在现有注册上注册一些其他类型的类型即可使其在任何地方适用。除非您实际检索单个类型的多个服务(通过在某处注入IEnumerable<T>(,否则这不会产生负面影响。

最新更新