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

はい、多くの依存サービスとリポジトリがあります。あなたのサービスには既に依存性注入を使用しているので、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

関連する問題