gpt4 book ai didi

c# - Entity Framework Core 2.2 在单元测试时拆除后不重置

转载 作者:太空宇宙 更新时间:2023-11-03 22:34:08 26 4
gpt4 key购买 nike

我正在尝试编写一些单元测试以尽可能多地覆盖我的 api,但我决定使用 InMemory 提供程序而不是使用数据库,而不是测试 EF 是否有效,而是我的植入是正确,但我遇到的是一个奇怪的副作用。

本质上发生的是被播种的对象的 id 值,不会在每次测试后重置。

在 MSTest 中,我实现了一个设置来为每个测试创建一个新的数据库上下文,为每个测试运行提供一个新名称,并确保在为我的数据库做种之前调用 EnsureCreated()。此外,我还实现了 TearDown 以确保正确处理数据库。

[TestClass]
public class CountryTests
{
private CdiContext Context { get; set; }

[TestInitialize]
public void Setup()
{
DbContextOptions<CdiContext> options = new DbContextOptionsBuilder<CdiContext>()
.UseInMemoryDatabase(databaseName: $"{Guid.NewGuid()}")
.Options;

Context = new CdiContext(options);
Context.Database.EnsureCreated();
Seed();
}

[TestCleanup]
public void TearDown()
{
Context.Database.EnsureDeleted();
}

private void Seed()
{
var service = new CoreDataService(Context);

var regions = new List<Region>
{
new Region
{
Name = "Asia",
State = RecordState.Active,
Created = DateTime.Now,
UserId = Guid.NewGuid().ToString()
},

new Region
{
Name = "Africa",
State = RecordState.Active,
Created = DateTime.Now,
UserId = Guid.NewGuid().ToString()
},

new Region
{
Name = "South America",
State = RecordState.Active,
Created = DateTime.Now,
UserId = Guid.NewGuid().ToString()
}
};

Context.Regions.AddRange(regions);
Context.SaveChanges();
}

[TestMethod]
public async Task CanAddCountry()
{
//-- arrange
var service = new CoreDataService(Context);

var userId = "133BC82D-FDE2-4124-9207-CD3465511AEB";
var region = await service.GetRegionById(1);

var country = new Country
{
Name = "Canada",
State = RecordState.Active,
UserId = userId,
Created = DateTime.Now,
RegionId = region.Id
};

//-- act
var results = await service.AddCountry(country);

//-- assert
Assert.IsTrue(results.Name == "Canada");
Assert.IsTrue(results.UserId == "133BC82D-FDE2-4124-9207-CD3465511AEB");
Assert.IsNotNull(results.Region);
}

[TestMethod]
public async Task CanGetCountries()
{
//-- arrange
var service = new CoreDataService(Context);

var userId = "133BC82D-FDE2-4124-9207-CD3465511AEB";
var region = service.GetRegionById(1);
var names = new[] {"Canada", "Wales", "Japan", "Australia", "Hawaii", "Germany"};

for (var x = 0; x < 5; x++)
{
await service.AddCountry(new Country
{
Name = names[x],
State = RecordState.Active,
UserId = userId,
Created = DateTime.Now,
RegionId = region.Id
});
}

//-- act
var results = await service.GetCountries();

//-- assert
Assert.IsNotNull(results);
Assert.IsTrue(results.Count == 5);
}

[TestMethod]
public async Task CanDeleteCountry()
{
//-- arrange
var service = new CoreDataService(Context);

var userId = "133BC82D-FDE2-4124-9207-CD3465511AEB";
var region = service.GetRegionById(1);
var names = new[] { "Canada", "Wales", "Japan", "Australia", "Hawaii", "Germany" };

for (var x = 0; x < 5; x++)
{
await service.AddCountry(new Country
{
Name = names[x],
State = RecordState.Active,
UserId = userId,
Created = DateTime.Now,
RegionId = region.Id
});
}

//-- act
await service.DeleteCountry(id: 2, userId: Guid.NewGuid().ToString());

var countries = await service.GetCountries();
var country = await service.GetCountryById(2);

//-- assert
Assert.IsTrue(countries.Count != 5);
Assert.IsNull(country);
}
}

现在当我运行它时,第三个测试失败了,因为它找不到正确的 id,这对我来说有点奇怪。

我最初认为这是 MSTest 的问题,但在 xUnit 中也注意到了相同的行为。

public class CdiTestBase : IDisposable
{
protected readonly CdiContext _context;

public CdiTestBase()
{
var options = new DbContextOptionsBuilder<CdiContext>()
.UseInMemoryDatabase(databaseName: $"{Guid.NewGuid()}")
.Options;

_context = new CdiContext(options);

_context.Database.EnsureCreated();

SeedRegions(_context);
}

public void Dispose()
{
_context.Database.EnsureDeleted();

_context.Dispose();
}

private void SeedRegions(CdiContext context)
{
var regions = new List<Region>
{
new Region
{
Name = "Asia",
State = RecordState.Active,
Created = DateTime.Now,
UserId = Guid.NewGuid().ToString()
},

new Region
{
Name = "Africa",
State = RecordState.Active,
Created = DateTime.Now,
UserId = Guid.NewGuid().ToString()
},

new Region
{
Name = "South America",
State = RecordState.Active,
Created = DateTime.Now,
UserId = Guid.NewGuid().ToString()
}
};

context.Regions.AddRange(regions);
context.SaveChanges();
}
}

public class CountryTests : CdiTestBase
{
[Fact]
public async Task CanAddCountry()
{
//-- arrange
var service = new CoreDataService(_context);

var userId = "133BC82D-FDE2-4124-9207-CD3465511AEB";
var region = await service.GetRegionById(1);

var country = new Country
{
Name = "Canada",
State = RecordState.Active,
UserId = userId,
Created = DateTime.Now,
RegionId = region.Id
};

//-- act
var results = await service.AddCountry(country);

//-- assert
Assert.True(results.Name == "Canada");
Assert.True(results.UserId == "133BC82D-FDE2-4124-9207-CD3465511AEB");
Assert.NotNull(results.Region);
}

[Fact]
public async Task CanGetCountries()
{
//-- arrange
var service = new CoreDataService(_context);

var userId = "133BC82D-FDE2-4124-9207-CD3465511AEB";
var region = service.GetRegionById(1);
var names = new[] { "Canada", "Wales", "Japan", "Australia", "Hawaii", "Germany" };

for (var x = 0; x < 5; x++)
{
await service.AddCountry(new Country
{
Name = names[x],
State = RecordState.Active,
UserId = userId,
Created = DateTime.Now,
RegionId = region.Id
});
}

//-- act
var results = await service.GetCountries();

//-- assert
Assert.NotNull(results);
Assert.True(results.Count == 5);
}

[Fact]
public async Task CanDeleteCountry()
{
//-- arrange
var service = new CoreDataService(_context);

var userId = "133BC82D-FDE2-4124-9207-CD3465511AEB";
var region = service.GetRegionById(1);
var names = new[] { "Canada", "Wales", "Japan", "Australia", "Hawaii", "Germany" };

for (var x = 0; x < 5; x++)
{
await service.AddCountry(new Country
{
Name = names[x],
State = RecordState.Active,
UserId = userId,
Created = DateTime.Now,
RegionId = region.Id
});
}

//-- act
await service.DeleteCountry(id: 2, userId: Guid.NewGuid().ToString());

var countries = await service.GetCountries();
var country = await service.GetCountryById(2);

//-- assert
Assert.True(countries.Count != 5);
Assert.Null(country);
}
}

如果我同时运行所有测试,我总是会遇到测试失败,但如果我单独运行每个测试,它们都会通过,这让我很困扰。

最佳答案

这是内存数据库自动生成 key 的一个已知问题,由 #6872 InMemory: Improve in-memory key generation 跟踪.

它已在即将发布的 3.0 版本中修复 - Each property uses independent in-memory integer key generation :

Old behavior

Before EF Core 3.0, one shared value generator was used for all in-memory integer key properties.

New behavior

Starting with EF Core 3.0, each integer key property gets its own value generator when using the in-memory database. Also, if the database is deleted, then key generation is reset for all tables.

Why

This change was made to align in-memory key generation more closely to real database key generation and to improve the ability to isolate tests from each other when using the in-memory database.

除了更新测试代码以不依赖硬编码的自动生成值(无论如何这都不好)之外,您目前无能为力。

关于c# - Entity Framework Core 2.2 在单元测试时拆除后不重置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55952419/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com