2017-06-14 18 views
1

エラー:インメモリDbContextはエラーをスローした場合、統合テスト

Message: System.InvalidOperationException : The instance of entity type 'Program' cannot be tracked because another instance of this type with the same key is already being tracked. When adding new entities, for most key types a unique temporary key value will be created if no key is set (i.e. if the key property is assigned the default value for its type). If you are explicitly setting key values for new entities, ensure they do not collide with existing entities or temporary values generated for other new entities. When attaching existing entities, ensure that only one entity instance with a given key value is attached to the context.

統合テスト:

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; 
     } 
    } 

問題は、私はメモリDBに新しい項目を追加するためにコンテキストを使用DoRequestForCreateWithCorrectData_ReturnCreatedHttpStatus方法で発生します。同じ問題が発生します。同時に項目に項目を追加したいので、間違った方法で初期化を行うと思います。

+1

問題があるかどうかはわかりませんが、 'SaveChanges' 'AddRangeAsync'の後に' 'await'または' 'Wait''を実行して終了しても良いとは言えません。単純に 'AddRange'ではなく –

答えて

0

問題は、プレデデッドデータのIDが1と1だったので、これは最初の間違いです。なぜ両方が一緒に機能しなかったのですか。別の問題は、以前のデータですでに使用されていたId 1で作成した新しいレコードを作成するときだったので、98と99にIDを変更しました。

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; 
    }