使用 InMemory 数据库覆盖 WebApplicationFactory

我正在自定义 WebApplicationFactory 以使用原始应用程序项目中的 Startup、appsettings。


目的是创建指向原始应用程序启动的集成测试。dbcontext 的 appsettings 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);

        }

    }

}



临摹微笑
浏览 147回答 1
1回答

德玛西亚99

您可以用来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>某处),否则这不会产生负面影响。
打开App,查看更多内容
随时随地看视频慕课网APP