2017-04-14 68 views
0

我正在为DbContext实现XUnit测试,看起来DbContext没有正确配置。当我调试第一个测试时,它可以工作,但为第二个测试抛出错误。该错误表示已添加listAds
加入手表后,在第二次测试中,_context为空,但在_context.Advertisements.AddRange(listAds);之前的值为AdvertisementsXUnit测试DbContext没有配置

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)); 
    } 
} 

回答

2

上下文处置,但不是“内存数据库”本身。

这是“通过设计”,允许您测试您正在测试的类正在创建它自己的DBContext实例的场景 - 否则您无法为它们准备数据。

你有两种可能性:

  1. 每个测试与databaseName用代码创建 “不同的数据库” 像.UseInMemoryDatabase(databaseName: Guid.NewGuid().ToString())

  2. 强制数据库毁坏/与context.Database.EnsureDeleted()创建后(或Dispose)重建。

对于您的测试类方法2看起来更合适,但是它取决于您。

Docs:https://docs.microsoft.com/en-us/ef/core/miscellaneous/testing/in-memory