如何在同一测试中更新最近添加的实体实例?
How can you update a recently added instance of an entity in the same test?
这是我的问题。我想在实现简单更新的控制器中测试一个函数。
我有错误代码:
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 是主键。
如何将数据放入 "database" 之前,而不发生此错误?
我的假设是我之前输入的数据将被跟踪并在 "tracked state" 中,因此无法更新。
这个想法是为了测试一切都在 UpdateData 中运行并执行更新。
新数据中唯一发生变化的是新的 "Data.Title",例如字符串数据类型。
我尝试更改 "testData" 的 EntityState,但这没有帮助。
我已经搜索并尝试了很多,但我不知所措。
执行 "db.Data.Update(data)" 时 UpdateData() 函数发生错误。
这是我编写的程序:
控制器:
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();
}
辅助函数:
public static ApplicationDbContext DbContext(){
var options = new DbContextOptionsBuilder<ApplicaitonDbContext>
.UseInMemoryDatabase(Guid.NewGuid().ToString())
.Options;
var context = new ApplicationDbContext(options);
return context;
}
测试函数:
[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
}
您可以 create/recreate 为 DataController
新建 DbContext,如下所示:
[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;
}
这是我的问题。我想在实现简单更新的控制器中测试一个函数。 我有错误代码:
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 是主键。
如何将数据放入 "database" 之前,而不发生此错误? 我的假设是我之前输入的数据将被跟踪并在 "tracked state" 中,因此无法更新。
这个想法是为了测试一切都在 UpdateData 中运行并执行更新。 新数据中唯一发生变化的是新的 "Data.Title",例如字符串数据类型。
我尝试更改 "testData" 的 EntityState,但这没有帮助。 我已经搜索并尝试了很多,但我不知所措。
执行 "db.Data.Update(data)" 时 UpdateData() 函数发生错误。
这是我编写的程序:
控制器:
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();
}
辅助函数:
public static ApplicationDbContext DbContext(){
var options = new DbContextOptionsBuilder<ApplicaitonDbContext>
.UseInMemoryDatabase(Guid.NewGuid().ToString())
.Options;
var context = new ApplicationDbContext(options);
return context;
}
测试函数:
[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
}
您可以 create/recreate 为 DataController
新建 DbContext,如下所示:
[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;
}