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

相关问题