为什么在单元测试期间,单独的DbContext会修改相同的DbSet?

时间:2018-12-17 04:41:23

标签: c# unit-testing entity-framework-core xunit in-memory-database

环境:

Xunit 2.3.1

Microsoft.EntityFrameworkCore.InMemory 2.1.0

我在三个不同的类中有三个测试方法,分别运行时可以通过,但是一起运行时,只有一个可以通过,而另外两个则失败。然后,当两者再次运行时-一个将通过而另一个将失败。

我发现了这个问题,我不确定为什么会发生这种情况。

我将显示一些代码,下面的代码是设计说明。

要点:

三个测试类:

public class FirstReviewRepoTest
public class SecondReviewRepoTest
public class ThirdReviewRepoTest

测试方法(它们的名称相同)

public void GetReviewDataTest(){}
public void GetReviewDataTest(){}
public void GetReviewDataTest(){}

请参阅下面充实的一项测试的更多代码:

[Trait("Repo","")]
public class FirstReviewRepoTest{

[Fact(DisplayName = "GetReviewDataTest")]
[Trait("Repo","FirstReviewRepo")]
pubic void GetReviewDataTest(){
var options = new DbContextOptionsBuilder<MyAppDbContext>().UseInMemoryDatabase(Guid.NewGuid().ToString()).Options;

using (MyAppDbContext context = new MyAppDbContext(options)){
    SeedDb(context);
    AddData(context);
    FirstReviewRepository repository = new FirstReviewRepository(context);

    FirstReviewDM dm = repository.GetReviewData(context.ItemInstanceDocumentInstance.Last().Id);
    FirstReviewDM expected = new FirstReviewDM{
       Analysis = "Analysis",
       Comments = "Comments",
       Solution = "Solution",
       Review = "Review",
       ReviewerToApproved = new KeyValuePair<string,bool>
}

Assert.Equal(expected,dm);
}

private void SeedDb(MyAppDbContext){
     CreateDocumentDescriptions(context);
     CreateTaskDescriptions(context);
     CreateDocumentFieldDescriptions(context);
     //... These go on...

     AddUsersWithRoleData(context); //This is where the issue begins
     context.SaveChanges();
}

private void AddUsersWithRoleData(MyAppDbContext context){
     List<Users> users = new List<Users>()
     {
         new Users { Name = "user1" },
         new Users { Name = "user2" },
         new Users { Name = "user3" },
         new Users { Name = "user4" },
         new Users { Name = "user5" },
         new Users { Name = "user6" },
         new Users { Name = "user7" },
         new Users { Name = "user8" }
{
}

设计说明:

最初,所有测试类都继承自定义了SeedDb(MyAppDbContext)的基类及其所有包含方法。 基类还有一个名为GetContextWithData()的方法,该方法返回一个新的MyAppDbContext,该表的表通过SeedDb()

填充。

我将所有内容移到了那里,因为关注继承使事情变得混乱了。

问题:

所有三个测试方法都创建一个存储库对象,并调用一个方法来获取各自的评论数据。在这些方法中,将调用Users dbSet,例如_context.Users.Single(x=> x.Id == document.AuthorId)。在所有三个测试文档中,AuthorId等于5。以某种方式,AddUsersWithRoleData的所有三个调用都将用户添加到看似相同的DbSet<Users>

因此,只有一个DbSet的用户ID为5。

我尝试过:

使测试按顺序运行。 不起作用

在添加到DbContext时为用户声明ID。 解决了此问题,但中断了将用户添加到DbSet的其他测试

1 个答案:

答案 0 :(得分:1)

未重置ID的原因是因为EfCore.InMemory(2.1)中的InMemory数据库共享密钥生成的值。其背后的原因是他们与Db无关。

可以在here深入了解此讨论