1

如何使用xUnit編寫測試用於服務層?我爲我的服務層使用依賴注入,但是如何在內存數據庫中使用它的實例呢?這是我到目前爲止,我遵循這個link,這裏是我來使用我的服務層,但它是一團糟,我不知道如何簡化它。使用即時通訊服務的接口,在我所有的控制器如何使用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

是的,你有很多依賴的服務和存儲庫。由於您已經爲您的服務使用了依賴注入,所以我建議您使用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

相關問題