2017-06-14 2 views
1

Erreur:InMemory DbContext lance erreur lors de tests d'intégration

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.

Test d'intégration:

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

problème se pose à la méthode DoRequestForCreateWithCorrectData_ReturnCreatedHttpStatus où j'utiliser le contexte pour ajouter un nouvel élément dans la mémoire DB. Le même problème se pose quand je veux ajouter plus d'éléments dans le contexte en même temps, donc je pense que je fais l'initialisation de manière incorrecte.

+1

Je ne sais pas si c'est le problème, mais 'SaveChanges' après 'AddRangeAsync' w/o' wait' ou 'Wait'-ing pour compléter ne sonne pas bien. Pourquoi ne pas simplement 'AddRange'. –

Répondre

0

Le problème était que les ID des données premade étaient 1 et 1, donc c'est la première erreur, pourquoi les deux n'ont pas fonctionné ensemble. Un autre problème a été lors de la création record qu'il a créé avec Id 1, qui a déjà été utilisé par des données premade, donc je ID juste changé dans premade à 98 et 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; 
    }