OnConfiguring DbContextOptionsBuilder 使我的数据库测试失败
OnConfiguring DbContextOptionsBuilder makes my database test fail
我正在尝试测试我的数据是否保存在数据库中。当我创建一个 ApplicationDbContext
带有内存数据库 SqliteConnection 连接的参数集的对象,我的测试失败了。我得到一个 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:
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 服务器进行持久化(由于对象关系映射功能,我更喜欢它)。
我正在尝试测试我的数据是否保存在数据库中。当我创建一个 ApplicationDbContext 带有内存数据库 SqliteConnection 连接的参数集的对象,我的测试失败了。我得到一个 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:
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 服务器进行持久化(由于对象关系映射功能,我更喜欢它)。