构建配置以作为参数传递给dbcontext,以便我可以在单元测试中使用它

时间:2017-09-26 22:41:40

标签: c# entity-framework unit-testing asp.net-core entity-framework-core

这是我的db上下文类

  public class WorldContext : IdentityDbContext<WorldUser>
  {
    private IConfigurationRoot _config;
    public WorldContext(IConfigurationRoot config, DbContextOptions options): base(options)
    {
        _config = config;
    }
    public DbSet<Trip> Trips { get; set; }
    public DbSet<Stop> Stops { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        base.OnConfiguring(optionsBuilder);
        optionsBuilder.UseSqlServer(_config["ConnectionStrings:WorldContextConnection"]);
    }
  }

以下是我的测试代码中我试图创建dbcontext实例的部分。

            var builder = new ConfigurationBuilder();
            var config = builder.Build();
            var options = new DbContextOptionsBuilder<WorldContext>()
                .UseInMemoryDatabase(Guid.NewGuid().ToString())
                .Options;
            var context = new WorldContext(config, options);

VS中没有错误并且构建正常,但测试失败了:

  

消息:System.ArgumentNullException:值不能为null。   参数名称:connectionString

[堆栈跟踪中有对此的引用:]

  

在   TheWorld.DAL.Models.WorldContext.OnConfiguring(DbContextOptionsBuilder   optionsBuilder)

1 个答案:

答案 0 :(得分:1)

首先,在测试类中创建DbContextOptions<WorldContext>的实例:

DbContextOptions<WorldContext> options;
var builder = new DbContextOptionsBuilder<WorldContext>();
builder.UseInMemoryDatabase(Guid.NewGuid().ToString());
options = builder.Options;

DbContextOptions实例将告诉WorldContext的所有配置,它将连接哪个数据库等。由于它是内存数据库,因此您不需要发送连接字符串(IMHO)。因此,您的WoldContext构造函数中不需要IConfigurationRoot参数。

然后,创建一个WorldContext类的实例并使用它:

var context = new WorldContext(options);

或者你说我不想改变我的构造函数,这是必要的,然后:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    base.OnConfiguring(optionsBuilder);
    if(string.IsNullOrEmpty(_config["ConnectionStrings:WorldContextConnection"]))
    {
        optionsBuilder.UseInMemoryDatabase(Guid.NewGuid().ToString());
    }
}