Как вы можете обновить недавно добавленный экземпляр объекта в том же тесте? - PullRequest
2 голосов
/ 16 июня 2020

Вот моя проблема. Я хотел бы протестировать функцию в контроллере, который реализует простое обновление. У меня есть код ошибки:

The instance of entity type 'Data' cannot be tracked because another instance with the same key value for {'Id'} is already being tracked.

В моем случае Data.Id является первичным ключом.

Как я могу поместить данные в «базу данных» раньше, чтобы эта ошибка не возникала? Я предполагаю, что данные, которые я ввел ранее, будут отслеживаться и находятся в «отслеживаемом состоянии», поэтому обновление невозможно.

Идея состоит в том, чтобы проверить, что все работает в UpdateData, а также выполняет обновление . Единственное, что изменяется в новых данных, - это, например, новый «Data.Title», который, например, является строковым типом данных.

Я пытался изменить EntityState на «testData», но это не помогло. Я уже много искал и пробовал, но я в недоумении.

Ошибка возникает в функции UpdateData () при выполнении «db.Data.Update (data)».

Вот что я запрограммировал:

Контроллер:

public async Task<IActionResult> UpdateData(DataDto dataDto){
        var data = mapper.Map<Data>(dataDto);
        //some updating happens here
        db.Data.Update(data);
        wait db.SaveChangesAsync();
        return Ok();
}

HelperFunction:

public static ApplicationDbContext DbContext(){
        var options = new DbContextOptionsBuilder<ApplicaitonDbContext>
           .UseInMemoryDatabase(Guid.NewGuid().ToString())
           .Options;

        var context = new ApplicationDbContext(options);
        return context;
}

TestFunction:

[Fact]
public async void UpdateDataTest(){
        //here happens some Mapper initialization
        await using var context = HelperFunction.DbContext();
        await context.Data.AddAsync(testData);
        await context.SaveChangesAsync();
        var dataController = new DataController(context, mapper){};
        var result = await dataController.UpdateData(changedTestData);
        // do some UnitTest

}

1 Ответ

1 голос
/ 17 июня 2020

Вы можете создать / воссоздать новый DbContext для DataController, примерно так:

[Fact]
public async void UpdateDataTest(){
        //here happens some Mapper initialization
        var contextId = Guid.NewGuid();
        await using (var context = HelperFunction.DbContext(contextId))
        {
            await context.Data.AddAsync(testData);
            await context.SaveChangesAsync();
        }
        await using var contextForController = HelperFunction.DbContext(contextId);
        var dataController = new DataController(contextForController, mapper){};
        var result = await dataController.UpdateData(changedTestData);
        // do some UnitTest    
}

Также вам нужно будет обновить HelperFunction.DbContext, чтобы он мог принимать Guid или просто какой-то строковый идентификатор, поэтому он получит доступ к той же области базы данных в памяти:

public static ApplicationDbContext DbContext(Guid? guid = null){
        var options = new DbContextOptionsBuilder<ApplicaitonDbContext>
           .UseInMemoryDatabase((guid ?? Guid.NewGuid()).ToString())
           .Options;

        var context = new ApplicationDbContext(options);
        return context;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...