c# - OnConfiguring DbContextOptionsBuilder 使我的数据库测试失败
问题描述
我正在尝试测试我的数据是否保存在数据库中。当我使用内存数据库 SqliteConnection 连接的参数集创建 ApplicationDbContext 对象时,我的测试失败。我得到一个 NullReferenceException。当我删除 ApplicationDbContext 对象中的覆盖 OnConfiguring 方法以连接使用我的其他构造函数设置的秘密时,我不再收到异常并且我的测试通过了。
在保持连接的秘密设置的同时进行此测试的最简单方法是什么?
这些是我的一些课程:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
private readonly AppSecrets _DbInfo;
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options, IOptions<AppSecrets>
DbInfo) : base(options)
{
_DbInfo = DbInfo.Value ?? throw new ArgumentException(nameof(DbInfo));
}
// Added for unit test
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options): base(options){ }
protected override void OnConfiguring(DbContextOptionsBuilder options) =>
options.UseSqlServer($"{_DbInfo.Database};User ID={_DbInfo.User};Password= {_DbInfo.Password};{_DbInfo.Options};");
public DbSet<UserBudget> Budgets { get; set; }
}
在 StartUp.cs
public void ConfigureServices(IServiceCollection services)
{
services.Configure<AppSecrets>(Configuration.GetSection("MyBudgetDB"));
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
}
测试
[Fact]
public async Task CreateBudget_CreatesCorrectly()
{
const string budgetName = "General budget";
double amount = 1000.0;
var connection = new SqliteConnection("DataSource=:memory:");
connection.Open();
var options = new DbContextOptionsBuilder<ApplicationDbContext>()
.UseSqlite(connection)
.Options;
// Run the test against one instance of the context
using (var context = new ApplicationDbContext(options))
{
context.Database.EnsureCreated();
var service = new BudgetService(context);
var cmd = new CreateBudgetCommand
{
InitAmount = amount,
};
var user = new ApplicationUser
{
Id = 123.ToString()
};
var recipeId = service.CreateBudget(cmd, user);
}
// Use a separate instance of the context to verify correct data was saved to database
using (var context = new ApplicationDbContext(options))
{
Assert.Equal(1000.0, await context.Budgets.CountAsync());
var budget = await context.Budgets.SingleAsync();
Assert.Equal(amount, budget.InitAmount);
}
}
谢谢,莱迪
解决方案
我尝试使用 SqlConnection 并在测试中手动设置 IOptions< AppSecrets > 但这更复杂,我得到了同样的错误。我为此采取了最简单,最合适的方式(我不知道这很容易);通过从 ApplicationDbContext 中删除 OnConfiguring() 方法并在 StartUp 中添加这些设置:
启动.cs
var config = new AppSecrets();
Configuration.Bind("MyBudgetDB", config);
services.AddSingleton(config);
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
$"{config.Database};User ID={config.User};Password={config.Password};{config.Options};"));
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{ }
public DbSet<UserBudget> Budgets { get; set; }
}
我现在可以测试我的数据是否正在使用 Sqlite 服务器进行持久化(由于对象关系映射功能,我更喜欢它)。
推荐阅读
- java - 所有线程都在等待某种障碍条件
- angular - 设置每个 css 文件的视图封装
- php - 如何用php执行curl命令
- postgresql - Phoenix 无法连接到 Heroku 的 PostgreSQL 服务器
- constraints - SystemVerilog 约束:约束之前已经写入的读地址
- ios - 标签的内容正在堆栈视图中裁剪
- excel - 所需对象:Excel 和 Word VBA、字典和存储范围
- python - 需要类似字节的对象 / ord() 预期的长度为 1 的字符串,但找到了 int (python 3.6)
- elasticsearch - Elasticsearch 索引在磁盘上占用的大小比它们看起来的要大
- javascript - Qualtrics:加载时动态设置滑块最大值