首页 > 解决方案 > 替换 WebApplicationFactory 中的 DbContext 进行单元测试

问题描述

我需要替换 WebApplicationFactory 中的上下文。我有 MyDbContext ,我想用 SQLite 上下文替换它以进行测试。

更换部件工作正常

.ConfigureServices(services =>
  {
    // Remove the app's ApplicationDbContext registration.
    var descriptor = services.SingleOrDefault(d => d.ServiceType == typeof(DbContextOptions<MyDbContext>));

    if (descriptor != null)
    {
      services.Remove(descriptor);
    }
    
    services.AddDbContext<MyDbContext>(builder =>
    {
      builder.UseSqlite(CreateInMemoryDatabase());
    });
  });

但是因为我在测试中从 Npgsql 迁移到 SQLite,所以我需要覆盖 OnModelCreating 中的一些默认值。我创建了一个新的数据库上下文类

public class MySqlLiteDbContext: MyDbContext
    {
        public MySqlLiteDbContext(DbContextOptions<MyDbContext> options) : base(options)
        {
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);

            modelBuilder.Entity<Record>()
                .Property(b => b.DateCreated)
                .HasDefaultValueSql("(datetime('now'))");

            ...
        }
    }

有什么方法可以注入MySqlLiteDbContext而不是MyDbContext强制 EnsureCreatedOnModelCreating用于 SQLite?是提取IMyDbContext选项吗?我还能做些什么来解决这个问题?

标签: unit-testingasp.net-core.net-coreentity-framework-core

解决方案


向服务容器注册 DbContext。打开 Startup.cs 并在 ConfigureServices 函数中,我们将使用 AddDbContext 扩展方法来添加我们的新 DbContext 并告诉它使用 SQLite 和我们的 appsettings.json 中的连接字符串。以下是完整的功能,前两行是我们添加的。

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<ContactsDbContext>(options =>
        options.UseSqlite(Configuration.GetConnectionString("DefaultConnection")));
    services.AddControllers();
    services.AddOpenApiDocument(document => 
        document.PostProcess = d => d.Info.Title = "Contacts API");
}

推荐阅读