仅向 DbContext 添加数据一次
Add data to DbContext only once
我创建了一个 XUnit fixture 来定义 EF Core 上下文初始数据:
public class ServiceProviderFixture : IDisposable {
public IServiceProvider Provider { get; private set; }
public ServiceProviderFixture() {
IServiceCollection services = new ServiceCollection();
services.AddDbContext<Context>(x => { x.UseInMemoryDatabase("Database"); });
Provider = services.BuildServiceProvider();
BuildContext();
}
private void BuildContext() {
Context context = Provider.GetService<Context>();
context.Countries.Add(new Country { Code = "fr", Name = "France" });
context.SaveChanges();
}
public void Dispose() { }
}
然后在一些测试中我使用它如下:
public class TestMethod1 : IClassFixture<ServiceProviderFixture> {
public Test(ServiceProviderFixture fixture) {
_fixture = fixture;
}
[Fact]
public async Task Test1() {
IServiceProvider provider = _fixture.Provider;
Context context = provider.GetService<Context>();
// Add test data to context
// Test some method
}
}
当我 运行 一个测试时,它进行得很好......但是当我使用 dotnet test
到 运行 所有测试时,我得到:
An item with the same key has already been added. Key: fr
The following constructor parameters did not have matching fixture data:
ServiceProviderFixture fixture)
我相信 BuildContext() 在同一上下文中每个 TestClass 被调用一次。
我该如何解决这个问题?
只要检查你的 BuildContext 是否有任何数据,如果没有就创建它,否则就什么都不做。或者您可以在测试完成后清理创建的数据。
private void BuildContext() {
Context context = Provider.GetService<Context>();
if(!context.Countries.Any())
{
context.Countries.Add(new Country { Code = "fr", Name = "France" });
context.SaveChanges();
}
}
因为您总是以相同的方式命名您的内存数据库,所以您总是会再次获得相同的数据库。
您必须为每个测试用例指定不同的名称(例如 Guid.NewGuid().ToString()
)。
services.AddDbContext<Context>(x =>
x.UseInMemoryDatabase($"Database{Guid.NewGuid()}")
);
我创建了一个 XUnit fixture 来定义 EF Core 上下文初始数据:
public class ServiceProviderFixture : IDisposable {
public IServiceProvider Provider { get; private set; }
public ServiceProviderFixture() {
IServiceCollection services = new ServiceCollection();
services.AddDbContext<Context>(x => { x.UseInMemoryDatabase("Database"); });
Provider = services.BuildServiceProvider();
BuildContext();
}
private void BuildContext() {
Context context = Provider.GetService<Context>();
context.Countries.Add(new Country { Code = "fr", Name = "France" });
context.SaveChanges();
}
public void Dispose() { }
}
然后在一些测试中我使用它如下:
public class TestMethod1 : IClassFixture<ServiceProviderFixture> {
public Test(ServiceProviderFixture fixture) {
_fixture = fixture;
}
[Fact]
public async Task Test1() {
IServiceProvider provider = _fixture.Provider;
Context context = provider.GetService<Context>();
// Add test data to context
// Test some method
}
}
当我 运行 一个测试时,它进行得很好......但是当我使用 dotnet test
到 运行 所有测试时,我得到:
An item with the same key has already been added. Key: fr
The following constructor parameters did not have matching fixture data:
ServiceProviderFixture fixture)
我相信 BuildContext() 在同一上下文中每个 TestClass 被调用一次。
我该如何解决这个问题?
只要检查你的 BuildContext 是否有任何数据,如果没有就创建它,否则就什么都不做。或者您可以在测试完成后清理创建的数据。
private void BuildContext() {
Context context = Provider.GetService<Context>();
if(!context.Countries.Any())
{
context.Countries.Add(new Country { Code = "fr", Name = "France" });
context.SaveChanges();
}
}
因为您总是以相同的方式命名您的内存数据库,所以您总是会再次获得相同的数据库。
您必须为每个测试用例指定不同的名称(例如 Guid.NewGuid().ToString()
)。
services.AddDbContext<Context>(x =>
x.UseInMemoryDatabase($"Database{Guid.NewGuid()}")
);