【发布时间】:2017-06-15 03:24:16
【问题描述】:
错误:
消息:System.InvalidOperationException:实体实例 无法跟踪类型“程序”,因为此类型的另一个实例 已使用相同的密钥进行跟踪。添加新实体时, 对于大多数键类型,如果没有,将创建一个唯一的临时键值 键已设置(即,如果为键属性分配了默认值 它的类型)。如果您要为新实体显式设置键值, 确保它们不会与现有实体或临时值发生冲突 为其他新实体生成。附加现有实体时, 确保只有一个具有给定键值的实体实例 附加到上下文中。
集成测试:
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;
}
}
问题出现在 DoRequestForCreateWithCorrectData_ReturnCreatedHttpStatus 方法中,我使用上下文将新项目添加到内存数据库中。当我想同时将更多项目添加到上下文中时会出现同样的问题,所以我认为我正在以错误的方式进行初始化。
【问题讨论】:
-
不确定这是否是问题所在,但
SaveChanges在AddRangeAsync之后没有await或Wait- 完成它听起来不太好。为什么不简单地AddRange。
标签: c# entity-framework integration-testing