c# - 实体框架核心唯一索引测试
问题描述
我有一个模型类:
public class Work
{
public long Id { get; set; }
[Required]
public string Name { get; set; }
}
我希望这Work.Name
将是独一无二的,所以我定义了DbContext
:
public class MyDbContext : DbContext
{
public MyDbContext () : base() { }
public MyDbContext (DbContextOptions<MyDbContext > options) : base(options) { }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Work>(entity =>
entity.HasIndex(e => e.Name).IsUnique()
);
}
public DbSet<Work> Works { get; set; }
}
我想测试一下,所以我有一个这样的测试:
[Fact]
public void Post_InsertDuplicateWork_ShouldThrowException()
{
var work = new Work
{
Name = "Test Work"
};
using (var context = new MyDbContext (options))
{
context.Works.Add(work);
context.SaveChanges();
}
using (var context = new MyDbContext (options))
{
context.Works.Add(work);
context.SaveChanges();
}
using (var context = new MyDbContext (options))
{
Assert.Equal(1, context.Works.Count());
}
}
(该option
对象包含设置InMemoryDatabase
)
我真的不知道要检查什么,但测试在 中Assert
失败,而不是在第二中SaveChanges()
。数据库 (the context
) 包含两个具有相同Name
.
我检查了所有相关问题,但没有看到任何人回答我的问题。
解决方案
正如其他人指出的那样,InMemory 数据库提供程序忽略了所有可能的约束。
我的建议是使用具有“内存中”功能的 Sqlite 提供程序,这将引发重复唯一键的异常。
public MyDbContext CreateSqliteContext()
{
var connectionString =
new SqliteConnectionStringBuilder { DataSource = ":memory:" }.ToString();
var connection = new SqliteConnection(connectionString);
var options = new DbContextOptionsBuilder<MyDbContext>().UseSqlite(connection);
return new MyDbContext(options);
}
private void Insert(Work work)
{
using (var context = CreateSqliteContext())
{
context.Works.Add(work);
context.SaveChanges();
}
}
[Fact]
public void Post_InsertDuplicateWork_ShouldThrowException()
{
var work1 = new Work { Name = "Test Work" };
var work2 = new Work { Name = "Test Work" };
Insert(work1);
Action saveDuplicate = () => Insert(work2);
saveDuplicate.Should().Throw<DbUpdateException>(); // Pass Ok
}
推荐阅读
- mysql - 如何在运行时创建多个 Jdbctemplate bean,指向不同的 Mysql 数据库?
- javascript - 我可以从 Save 类中使用源元访问属性吗?
- laravel - 从 Laravel 中使用 Bootstrap 和 ChartJS 制作的 HTML 页面生成 PDF
- mysql - 从相同的值 mysql 5.7 中选择
- c++ - 使用 emcc 将 C++ 代码编译为 WASM 的问题
- android - 如何从 Android Pager 3 中的 RecyclerView 中删除丢弃的项目?
- python - 将 pandas GroupBy 中的多个列值聚合为 dict
- python - 为什么我们使用这个循环来进行干净的布局
- c++ - 使用 PQexecParams 插入二进制浮点数
- reactjs - 如何防止在反应选择中接受多个空格?