如何使用xUnit为服务层编写测试?我正在为我的服务层使用依赖注入,但是如何在内存数据库中使用它来创建它的实例呢?这是我到目前为止所做的,我遵循这个link,这就是我使用我的服务层,但它是一个烂摊子,我不知道如何简化它。我在所有控制器中使用服务接口
[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
对其他服务,存储库和上下文有很多依赖。
答案 0 :(得分: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中测试和验证这些代码行,但它应该会给你一个想法。我们在我们的应用程序中也使用了这种方法,您可以使用自己喜欢的IoC容器。您还需要存储库和服务的接口,但最好还是使用它们: - )