【问题标题】:InMemory DbContext throws error when integration testing集成测试时 InMemory DbContext 抛出错误
【发布时间】: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 方法中,我使用上下文将新项目添加到内存数据库中。当我想同时将更多项目添加到上下文中时会出现同样的问题,所以我认为我正在以错误的方式进行初始化。

【问题讨论】:

  • 不确定这是否是问题所在,但 SaveChangesAddRangeAsync 之后没有 awaitWait- 完成它听起来不太好。为什么不简单地AddRange

标签: c# entity-framework integration-testing


【解决方案1】:

问题是来自预制数据的 ID 是 1 和 1,所以这是第一个错误,为什么两者不能一起工作。另一个问题是在创建新记录时,它使用 Id 1 创建,它已经被预制数据使用,所以我只是将 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;
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-08-29
    • 1970-01-01
    • 2020-07-27
    • 2014-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-25
    相关资源
    最近更新 更多