C# 集成测试时InMemory DbContext引发错误
错误: 消息:System.InvalidOperationException:实体的实例 无法跟踪类型“Program”,因为此类型的另一个实例 已在跟踪具有相同密钥的。在添加新实体时, 对于大多数键类型,如果没有,将创建唯一的临时键值 设置关键点(即,如果为关键点属性指定了 其类型)。如果要显式设置新实体的键值, 确保它们不会与现有实体或临时值冲突 为其他新实体生成。在附加现有实体时, 确保只创建一个具有给定键值的实体实例 依附于上下文 集成测试:C# 集成测试时InMemory DbContext引发错误,c#,entity-framework,integration-testing,C#,Entity Framework,Integration Testing,错误: 消息:System.InvalidOperationException:实体的实例 无法跟踪类型“Program”,因为此类型的另一个实例 已在跟踪具有相同密钥的。在添加新实体时, 对于大多数键类型,如果没有,将创建唯一的临时键值 设置关键点(即,如果为关键点属性指定了 其类型)。如果要显式设置新实体的键值, 确保它们不会与现有实体或临时值冲突 为其他新实体生成。在附加现有实体时, 确保只创建一个具有给定键值的实体实例 依附于上下文 集成测试: public class ProgramC
public class ProgramControllerIntegrationTests : MappingTestsHelper
{
private readonly IMapper _mapper;
private readonly Repository<ApplicationDbContext> _repository;
private ProgramService _programService;
private readonly ProgramController _classUnderTest;
private readonly ValidatorService _validatorService;
private readonly FluentValidatorFactory _fluentValidatorFactory;
private readonly ClaimsService _claimsService;
public ProgramControllerIntegrationTests()
{
var container = new Container();
container.Configure(c => {
c.AddRegistry<DependencyInjectionRegistry>();
c.For<AbstractValidator<CreateViewModel>>().Use<CreateViewModelValidator>();
});
_mapper = Mapper.Instance;
_repository = new Repository<ApplicationDbContext>(GetContextWithData());
_programService = new ProgramService(_repository, _mapper);
_fluentValidatorFactory = new FluentValidatorFactory(container);
_validatorService = new ValidatorService(_fluentValidatorFactory);
_claimsService = new ClaimsService();
_classUnderTest = new ProgramController(_programService, _claimsService, _mapper, _validatorService);
}
public class GetAll : ProgramControllerIntegrationTests
{
[Fact]
public async void DoRequestForAllPrograms_ReturnSuccessHttpStatusAndListViewModelList()
{
var result = await _classUnderTest.GetAll() as ObjectResult; ;
result.ShouldBeOfType<OkObjectResult>();
result.StatusCode.ShouldBe(200);
result.Value.ShouldBeOfType<List<ListViewModel>>();
}
}
public class Create : ProgramControllerIntegrationTests
{
[Fact]
public async void DoRequestForCreateWithCorrectData_ReturnCreatedHttpStatus()
{
var createviewmodel = new CreateViewModel
{
Name = "Muskel Deutsche Program",
Length = 1,
TimesPerWeek = 3,
Type = (byte)ProgramTypeEnum.MuscleGain
};
var result = await _classUnderTest.Create(createviewmodel) as ObjectResult;
result.ShouldBeOfType<OkObjectResult>();
result.StatusCode.ShouldBe(201);
}
[Fact]
public async void DoRequestForCreateWithMissingData_ReturnBadRequestHttpStatus()
{
var createviewmodel = new CreateViewModel
{
Type = (byte)ProgramTypeEnum.MuscleGain
};
var result = await _classUnderTest.Create(createviewmodel) as ObjectResult;
result.ShouldBeOfType<BadRequestObjectResult>();
result.StatusCode.ShouldBe(400);
}
}
private ApplicationDbContext GetContextWithData()
{
var options = new DbContextOptionsBuilder<ApplicationDbContext>()
.UseInMemoryDatabase(Guid.NewGuid().ToString())
.Options;
var context = new ApplicationDbContext(options);
var programs = new List<Context.Models.Program>
{
new Context.Models.Program
{
CreatedBy = "d0806514-cbce-47b7-974f-c50f77d5e89c",
CreatedDate = new DateTime(2010, 10, 10),
Id = 1,
IsActive = true,
IsDeleted = false,
Length = 1,
ModifiedBy = "d0806514-cbce-47b7-974f-c50f77d5e89c",
ModifiedDate = new DateTime(2010, 10, 10),
Name = "Big Muscle",
TimesPerWeek = 1
},
//new Context.Models.Program
//{
// CreatedBy = "d0806514-cbce-47b7-974f-c50f77d5e89c",
// CreatedDate = new DateTime(2010, 10, 10),
// Id = 1,
// IsActive = true,
// IsDeleted = false,
// Length = 1,
// ModifiedBy = "d0806514-cbce-47b7-974f-c50f77d5e89c",
// ModifiedDate = new DateTime(2010, 10, 10),
// Name = "Stay Fit",
// TimesPerWeek = 1
//}
};
context.AddRangeAsync(programs);
context.SaveChanges();
return context;
}
}
公共类ProgramControllerIntegrationTests:MappingTestsHelper
{
专用只读IMapper\u映射器;
私有只读存储库_存储库;
私人节目服务(ProgramService);;
专用只读程序控制器_classUnderTest;
专用只读验证器服务\u验证器服务;
私有只读FluentValidatorFactory\u FluentValidatorFactory;
私人只读索赔服务(U索赔服务);
公共程序控制器集成测试()
{
var container=新容器();
container.Configure(c=>{
c、 AddRegistry();
c、 For().Use();
});
_mapper=mapper.Instance;
_repository=新存储库(GetContextWithData());
_programService=新的programService(\u存储库,\u映射器);
_fluentValidatorFactory=新的fluentValidatorFactory(容器);
_validatorService=新的validatorService(\u fluentValidatorFactory);
_claimsService=新的claimsService();
_classUnderTest=新的程序控制器(_programService、_claimsService、_mapper、_validatorService);
}
公共类GetAll:ProgramControllerIntegrationTests
{
[事实]
public async void DoRequestForAllPrograms\u returnsHttpStatusandListViewModelList()成功
{
var result=await_classUnderTest.GetAll()作为ObjectResult;
result.ShouldBeOfType();
结果.状态代码.应为(200);
result.Value.ShouldBeOfType();
}
}
创建公共类:ProgramControllerIntegrationTests
{
[事实]
公共异步void DoRequestForCreateWithCorrectData_ReturnCreatedHttpStatus()
{
var createviewmodel=新的createviewmodel
{
Name=“Muskel Deutsche计划”,
长度=1,
每周时间=3,
类型=(字节)ProgramTypeEnum.MuscleGain
};
var result=await_classUnderTest.Create(createviewmodel)作为ObjectResult;
result.ShouldBeOfType();
结果.状态代码.应为(201);
}
[事实]
公共异步void DoRequestForCreateWithMissingData_ReturnBadRequestHttpStatus()
{
var createviewmodel=新的createviewmodel
{
类型=(字节)ProgramTypeEnum.MuscleGain
};
var result=await_classUnderTest.Create(createviewmodel)作为ObjectResult;
result.ShouldBeOfType();
结果.状态代码.应为(400);
}
}
私有应用程序DBContext GetContextWithData()
{
var options=new DbContextOptionsBuilder()
.UseInMemoryDatabase(Guid.NewGuid().ToString())
.选择;
var context=新的ApplicationDbContext(选项);
var程序=新列表
{
新的Context.Models.Program
{
CreatedBy=“d0806514-cbce-47b7-974f-c50f77d5e89c”,
CreatedDate=新日期时间(2010,10,10),
Id=1,
IsActive=true,
IsDeleted=false,
长度=1,
修改为=“d0806514-cbce-47b7-974f-c50f77d5e89c”,
ModifiedDate=新日期时间(2010,10,10),
Name=“大肌肉”,
每周时间=1
},
//新的Context.Models.Program
//{
//CreatedBy=“d0806514-cbce-47b7-974f-c50f77d5e89c”,
//CreatedDate=新日期时间(2010,10,10),
//Id=1,
//IsActive=true,
//IsDeleted=false,
//长度=1,
//修改为=“d0806514-cbce-47b7-974f-c50f77d5e89c”,
//ModifiedDate=新日期时间(2010,10,10),
//Name=“保持健康”,
//每周时间=1
//}
};
addRangeSync(程序);
SaveChanges();
返回上下文;
}
}
问题出现在DoRequestForCreateWithCorrectData_ReturnCreatedHttpStatus方法中,我使用上下文将新项添加到内存数据库中。当我想同时向上下文中添加更多项时,也会出现同样的问题,所以我认为我的初始化方式是错误的。问题是来自预制数据的Id是1和1,所以这是第一个错误,为什么两者不能一起工作。另一个问题是当创建Id为1的新记录时,它已经被premade数据使用,所以我只是将premade中的Id更改为98和99
private ApplicationDbContext GetContextWithData()
{
var options = new DbContextOptionsBuilder<ApplicationDbContext>()
.UseInMemoryDatabase(Guid.NewGuid().ToString())
.Options;
var context = new ApplicationDbContext(options);
var programs = new List<Context.Models.Program>
{
new Context.Models.Program
{
CreatedBy = "d0806514-cbce-47b7-974f-c50f77d5e89c",
CreatedDate = new DateTime(2010, 10, 10),
Id = 98,
IsActive = true,
IsDeleted = false,
Length = 1,
ModifiedBy = "d0806514-cbce-47b7-974f-c50f77d5e89c",
ModifiedDate = new DateTime(2010, 10, 10),
Name = "Big Muscle",
TimesPerWeek = 1
},
new Context.Models.Program
{
CreatedBy = "d0806514-cbce-47b7-974f-c50f77d5e89c",
CreatedDate = new DateTime(2010, 10, 10),
Id = 99,
IsActive = true,
IsDeleted = false,
Length = 1,
ModifiedBy = "d0806514-cbce-47b7-974f-c50f77d5e89c",
ModifiedDate = new DateTime(2010, 10, 10),
Name = "Stay Fit",
TimesPerWeek = 1
}
};
context.AddRange(programs);
context.SaveChanges();
return context;
}
private ApplicationDbContext GetContextWithData()
{
var options=new DbContextOptionsBuilder()
.UseInMemoryDatabase(Guid.NewGuid().ToString())
.选择;
var context=新的ApplicationDbContext(选项);