Почему отдельные DbContexts модифицируют один и тот же DbSet во время модульных тестов? - PullRequest
0 голосов
/ 17 декабря 2018

Enviornment:

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()

Я переместил все это оттуда, так как наследство опасалось, что что-то испортило.

Проблема:

Все три метода тестирования создают объект репозитория и вызывают метод для получения соответствующих данных обзора.В этих методах вызывается пользователь dbSet, например, _context.Users.Single(x=> x.Id == document.AuthorId).Во всех трех тестах document.AuthorId равен 5. Каким-то образом все три вызова AddUsersWithRoleData добавляют пользователей, казалось бы, к одному и тому же DbSet<Users>

Таким образом, только один DbSet имеет пользователя с Id= 5.

Я пробовал:

Выполнение тестов по порядку. Не работает

Объявление идентификаторов для пользователей при добавлении в DbContext. Исправляет эту проблему, но нарушает другие тесты, которые добавляют пользователей в DbSet

1 Ответ

0 голосов
/ 17 декабря 2018

Причина, по которой идентификаторы не сбрасываются, заключается в том, что базы данных InMemory в EfCore.InMemory (2.1) совместно используют сгенерированные значения ключа.Причиной этого является то, что они должны быть независимыми от Db.

Это обсуждение можно найти в глубине здесь

...