我正在尝试编写一个基于 ASP.Net 核心的相当简单的 web 服务的单元测试。对于持久性,我使用 Entity Framework 核心来访问 SQL 数据库。
在单元测试中,我显然不想要一个可以从一个测试渗入另一个测试的数据库。经过一番搜索,我找到了这篇文章 https://docs.microsoft.com/en-us/ef/core/miscellaneous/testing/in-memory .我的测试代码现在看起来像这样:
[Fact]
public void Test_method()
{
var options = new DbContextOptionsBuilder<ServiceContext>()
.UseInMemoryDatabase(databaseName: "Test_method") // Unique name for each test
.Options;
using (var context = new ServiceContext(options))
{
// Add test data
context.Dataset.Add(new ...);
context.SaveChanges();
}
using (var context = new ServiceContext(options))
{
// Perform tests
var controller = new Controller(new Service(context));
...
}
}
这几乎有效,每个测试用例都从一个空的数据库开始。但是分配给 testdata 元素的 ID 不会重置。因此,如果我有一个向其数据库添加一个元素的测试和另一个添加两个元素的测试,则第一个测试中的测试元素可能会获得 ID 1 或 3,具体取决于这两个测试的执行顺序。
有没有办法确保 ID 在单个测试方法中始终以 1 开头?当 ID 取决于其他测试是否在当前测试之前运行时,执行基于 ID 的查找的测试代码确实非常难看。
最佳答案
Entity Framework inmemory database
不会重置其自动增量计数器。
以下是来自 Github 问题的声明:
The InMemory provider doesn't the Identity pattern you would get in a relational database. When a column is configured as ValueGeneratedOnAdd it uses values from a single generator for all tables. This would be similar to having all tables setup to use a single sequence in a relational database. This raises one of the important design principles of our InMemory provider, which is that we are not trying to emulate a relational database. This becomes more important as we start to light up non-relational providers.
If you want to have a database that acts like a relational database, but doesn't have the overhead of I/O, then we'd recommend using an In-Memory SQLite database - http://www.sqlite.org/inmemorydb.html.
We're going to update our testing docs to make the SQLite option more prominent.
来源:https://github.com/aspnet/EntityFrameworkCore/issues/6872
因此,您可以考虑在每次运行测试时手动重置计数器(例如
ALTER TABLE mytable AUTO_INCREMENT = 1;
),或者使用帖子中提到的不同 sql 提供程序。
关于c# - 使用 Entity Framework DB 上下文 : Does not reset ID counter 进行单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55184013/