【问题标题】:Build config to pass in to dbcontext as an argument so I can use it in a unit test构建配置以作为参数传递给 dbcontext,以便我可以在单元测试中使用它
【发布时间】:2017-09-26 22:41:39
【问题描述】:

这是我的数据库上下文类

  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:值不能为空。 参数名称:连接字符串

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

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

【问题讨论】:

  • 它说连接字符串丢失。你确定你在配置文件中设置了连接字符串吗?
  • @ChetanRanpariya 我想这是通过配置参数传入的,这是我正在努力构建的。虽然因为我用它来测试我在选项中使用.InMemoryDatabase所以也许我不应该使用我的实际连接字符串,因为我不想点击实际的数据库......(?)

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


【解决方案1】:

首先,在您的测试类中创建DbContextOptions&lt;WorldContext&gt; 的实例:

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

DbContextOptions 实例将告诉 WorldContext 的所有配置,它将连接哪个数据库等。由于它是一个内存数据库,您不需要发送连接字符串(恕我直言)。所以你的 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());
    }
}

【讨论】:

  • 这适用于 WorldContext 接受的唯一参数是选项参数。我的情况是我需要传入配置和选项。请参阅我的代码开头:public WorldContext(IConfigurationRoot config, DbContextOptions options)
  • - 我不能只删除 worldcontext 类中的配置,否则我会破坏我的项目的其余部分。我正在使用来自 Pluralsight 的 Shaun Wildermuth 的示例项目。不幸的是,他没有给出在项目中使用 EF 进行单元测试的示例。
  • 太棒了! - 测试通过了,但这破坏了我的启动代码,尽管我需要添加的是:else { optionsBuilder.UseSqlServer(_config["ConnectionStrings:WorldContextConnection"]); }
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多