XUnit 测试 DbContext 没有处理
XUnit Test DbContext did not dispose
我正在为 DbContext 实施 XUnit 测试,DbContext 似乎没有正确处理。当我调试第一个测试时,它有效,但在第二个测试中,抛出一个错误 listAds
已经添加。
添加手表后,在第二次测试中,_context
为空,但在调用 _context.Advertisements.AddRange(listAds);
之前它具有 Advertisements
的值。
public class AdsServiceTest: IDisposable
{
private readonly DbContextOptions<SensingSiteDbContext> _options;
private readonly SensingSiteDbContext _context;
private readonly AdsService _AdsService;
public AdsServiceTest()
{
//initialize db options
_options = new DbContextOptionsBuilder<SensingSiteDbContext>()
.UseInMemoryDatabase()
.Options;
//get service
_context = new SensingSiteDbContext(_options);
//initialize dbcontext
List<Ads> listAds = new List<Ads>() {
new Ads(){ Id=1,AdsName="Ads1", Deleted=false},
new Ads(){ Id=2,AdsName="Ads2", Deleted=false},
new Ads(){ Id=3,AdsName="Ads3", Deleted=false}
};
//In the second test method, it throw errors, listAds already exist in
_context.Advertisements.AddRange(listAds);
_context.SaveChanges();
BaseLib.SSDbContext<Ads, AdsService> ssDbContent = new BaseLib.SSDbContext<Ads, AdsService>(_context);
_AdsService = ssDbContent.GetService((x, y) => new AdsService(x, y));
}
public void Dispose()
{
_context.Dispose();
}
[Theory]
[InlineData(1)]
public void FindById(int id)
{
Ads adsResult = _AdsService.FindById(id);
Ads adsTarget = _context.Advertisements.Find(id);
Assert.Equal(adsResult.AdsName, adsTarget.AdsName);
//Assert.True(adsTarget.Equals(adsResult));
}
[Fact]
public void GetAll()
{
var adsResult = _AdsService.GetAll();
var adsTarget = _context.Advertisements.ToList();
Assert.Equal(adsResult.Count(),adsTarget.Count());
//Did not work all the time
//Assert.True(adsTarget.Equals(adsResult));
}
}
上下文已处理,但 "in-memory database" 本身未处理。
这 "by design" 允许您测试场景,其中 class 您测试的是创建它自己的 DBContext 实例 - 否则您无法为它们准备数据。
你有两种可能:
使用 databaseName
为每个测试创建 "different databases",代码如 .UseInMemoryDatabase(databaseName: Guid.NewGuid().ToString())
在创建后(或在 Dispose
中)用 context.Database.EnsureDeleted()
强制数据库 destroy/recreate。
为了你的测试class方法2看起来更合适,但这取决于你。
文档:https://docs.microsoft.com/en-us/ef/core/miscellaneous/testing/in-memory
我正在为 DbContext 实施 XUnit 测试,DbContext 似乎没有正确处理。当我调试第一个测试时,它有效,但在第二个测试中,抛出一个错误 listAds
已经添加。
添加手表后,在第二次测试中,_context
为空,但在调用 _context.Advertisements.AddRange(listAds);
之前它具有 Advertisements
的值。
public class AdsServiceTest: IDisposable
{
private readonly DbContextOptions<SensingSiteDbContext> _options;
private readonly SensingSiteDbContext _context;
private readonly AdsService _AdsService;
public AdsServiceTest()
{
//initialize db options
_options = new DbContextOptionsBuilder<SensingSiteDbContext>()
.UseInMemoryDatabase()
.Options;
//get service
_context = new SensingSiteDbContext(_options);
//initialize dbcontext
List<Ads> listAds = new List<Ads>() {
new Ads(){ Id=1,AdsName="Ads1", Deleted=false},
new Ads(){ Id=2,AdsName="Ads2", Deleted=false},
new Ads(){ Id=3,AdsName="Ads3", Deleted=false}
};
//In the second test method, it throw errors, listAds already exist in
_context.Advertisements.AddRange(listAds);
_context.SaveChanges();
BaseLib.SSDbContext<Ads, AdsService> ssDbContent = new BaseLib.SSDbContext<Ads, AdsService>(_context);
_AdsService = ssDbContent.GetService((x, y) => new AdsService(x, y));
}
public void Dispose()
{
_context.Dispose();
}
[Theory]
[InlineData(1)]
public void FindById(int id)
{
Ads adsResult = _AdsService.FindById(id);
Ads adsTarget = _context.Advertisements.Find(id);
Assert.Equal(adsResult.AdsName, adsTarget.AdsName);
//Assert.True(adsTarget.Equals(adsResult));
}
[Fact]
public void GetAll()
{
var adsResult = _AdsService.GetAll();
var adsTarget = _context.Advertisements.ToList();
Assert.Equal(adsResult.Count(),adsTarget.Count());
//Did not work all the time
//Assert.True(adsTarget.Equals(adsResult));
}
}
上下文已处理,但 "in-memory database" 本身未处理。
这 "by design" 允许您测试场景,其中 class 您测试的是创建它自己的 DBContext 实例 - 否则您无法为它们准备数据。
你有两种可能:
使用
databaseName
为每个测试创建 "different databases",代码如.UseInMemoryDatabase(databaseName: Guid.NewGuid().ToString())
在创建后(或在
Dispose
中)用context.Database.EnsureDeleted()
强制数据库 destroy/recreate。
为了你的测试class方法2看起来更合适,但这取决于你。
文档:https://docs.microsoft.com/en-us/ef/core/miscellaneous/testing/in-memory