1

Как написать тест с использованием xUnit для служебного уровня? Я использую инъекцию зависимостей для моего уровня обслуживания, но как я могу сделать экземпляр из него в базе данных памяти? Вот что я получил до сих пор, я следую этому link, и вот что я придумал, чтобы использовать мой сервисный уровень, но это был беспорядок, и я не знаю, как его упростить. Im, используя интерфейс сервиса во всех моих контроллерахКак написать тест с использованием xUnit для уровня обслуживания?

[Fact] 
    public void Add_writes_to_database() 
    { 
     var options = new DbContextOptionsBuilder<ApplicationDbContext>() 
      .UseInMemoryDatabase(databaseName: "Add_writes_to_database") 
      .Options; 

     // Run the test against one instance of the context 
     using (var context = new ApplicationDbContext(options)) 
     { 
      var productRepo = new Repository<Product>(context); 
      var categoryRepo = new Repository<Category>(context); 
      var categoryMappingRepo = new Repository<ProductCategoryMapping>(context); 
      var categoryService = new CategoryService(context, categoryRepo, categoryMappingRepo); 
      var manufacturerRepo = new Repository<Manufacturer>(context); 
      var manufacturerMappingRepo = new Repository<ProductManufacturerMapping>(context); 
      var manufacturerService = new ManufacturerService(context, manufacturerRepo, manufacturerMappingRepo); 
      var imageRepo = new Repository<Image>(context); 
      var imageMappingRepo = new Repository<ProductImageMapping>(context); 
      var imageService = new ImageManagerService(imageRepo, imageMappingRepo); 
      var specificationRepo = new Repository<Specification>(context); 
      var specificationMappingRepo = new Repository<ProductSpecificationMapping>(context); 
      var specificationService = new SpecificationService(context, specificationRepo, specificationMappingRepo); 
      var productService = new ProductService(context, productRepo, categoryService, manufacturerService, imageService, specificationService); 

      var product = new Product() { Id = Guid.NewGuid(), Name = "Product1", Price = 100m }; 

      productService.InsertProduct(product); 
     } 

     // Use a separate instance of the context to verify correct data was saved to database 
     using (var context = new ApplicationDbContext(options)) 
     { 
      var productRepo = new Repository<Product>(context); 
      var categoryRepo = new Repository<Category>(context); 
      var categoryMappingRepo = new Repository<ProductCategoryMapping>(context); 
      var categoryService = new CategoryService(context, categoryRepo, categoryMappingRepo); 
      var manufacturerRepo = new Repository<Manufacturer>(context); 
      var manufacturerMappingRepo = new Repository<ProductManufacturerMapping>(context); 
      var manufacturerService = new ManufacturerService(context, manufacturerRepo, manufacturerMappingRepo); 
      var imageRepo = new Repository<Image>(context); 
      var imageMappingRepo = new Repository<ProductImageMapping>(context); 
      var imageService = new ImageManagerService(imageRepo, imageMappingRepo); 
      var specificationRepo = new Repository<Specification>(context); 
      var specificationMappingRepo = new Repository<ProductSpecificationMapping>(context); 
      var specificationService = new SpecificationService(context, specificationRepo, specificationMappingRepo); 
      var productService = new ProductService(context, productRepo, categoryService, manufacturerService, imageService, specificationService); 

      Assert.Equal(1, productService.GetAllProduct().Count()); 
     } 
    } 

моего productService есть много зависимостей на другие службы, хранилище и контекст.

ответ

1

Да, у вас есть много зависимых сервисов и хранилищ. Поскольку вы уже используете Dependency Injection для своих услуг, я предлагаю вам использовать контейнер IoC. Это позволит не только удалить много кода для настройки ваших интеграционных тестов, но также поможет вам легко разрешить любую услугу в вашем приложении.

Вы можете создать класс для ваших отображений типа так:

public class Services 
{ 
    private readonly DbContextOptions _options; 
    private readonly IUnityContainer _container; 

    public Services(DbContextOptions options) 
    { 
     _options = options; 
     _container = new UnityContainer(); 
     RegisterTypes(); 
    } 

    private void RegisterTypes() 
    { 
     _container.RegisterType<IApplicationDbContext, ApplicationDbContext>(new ContainerControlledLifetimeManager(), new InjectionConstructor(_options)); 
     _container.RegisterType<IProductService, ProductService>(new ContainerControlledLifetimeManager()); 
     _container.RegisterType<ISpecificationService, SpecificationService>(new ContainerControlledLifetimeManager()); 
     _container.RegisterType<IImageManagerService, ImageManagerService>(new ContainerControlledLifetimeManager()); 
     _container.RegisterType<IRepository<ProductSpecificationMapping>, Repository<ProductSpecificationMapping>>(new ContainerControlledLifetimeManager()); 
     // etc ... 
    } 

    public T Get<T>() 
    { 
     return _container.Resolve<T>(); 
    } 
} 

Тогда вы способны минимизировать код теста, который необходим для решения продукта услуги:

[Fact] 
public void Add_writes_to_database() 
{ 
    var options = new DbContextOptionsBuilder<ApplicationDbContext>() 
     .UseInMemoryDatabase(databaseName: "Add_writes_to_database") 
     .Options; 

    var services = new Services(options); 
    var target = services.Get<IProductService>(); 

    // to your testing 
} 

Я не тестировал и не проверял эти строки кода в VS, но он должен дать вам представление. Мы также используем этот подход с Unity в одном из наших приложений, и вы можете использовать свой любимый контейнер IoC. Вам также нужны интерфейсы для ваших репозиториев и сервисов, но лучше их иметь в любом случае :-)

+0

любая идея, как я могу это сделать, я использую стандартную инъекцию зависимости asp.net по умолчанию? – kram005