繁体   English   中英

使用ASP.NET Boilerplate对ID​​omainService进行单元测试

[英]Unit testing for IDomainService with ASP.NET Boilerplate

我正在对ABP进行单元测试,但以下错误提示:

无法访问已处置的对象。 导致此错误的常见原因是,处理从依赖项注入中解决的上下文,然后稍后尝试在应用程序中的其他位置使用相同的上下文实例。 如果在上下文上调用Dispose()或将上下文包装在using语句中,则可能会发生这种情况。 如果使用依赖项注入,则应让依赖项注入容器负责处理上下文实例。 对象名称:“ XXXDbContext”。

这是我的详细步骤:

  1. 应用服务

     public async Task<ProductDto> CreateProduct(CreateProductInput input) { var existing = // await _productManager.ProductRepository.FirstOrDefaultAsync(p => p.Name == input.Name); await _productManager.Products.Where(p => p.Name == input.Name).FirstOrDefaultAsync(); if (existing != null) throw new UserFriendlyException(L("ExistedRepeatedAd")); var newAdEntity = ObjectMapper.Map<Product>(input); // Rest of the code } 
  2. 产品经理

     public class ProductManager : IDomainService { private readonly IRepository<Product, long> _ProductRepository; private readonly IUnitOfWorkManager _unitOfWorkManager; public ProductsManager( IRepository<Product, long> ProductRepository, IUnitOfWorkManager unitOfWorkManager) { _ProductRepository = ProductRepository; _unitOfWorkManager = unitOfWorkManager; } #region Products public IRepository<Product, long> ProductRepository { get { return _ProductRepository; } } public IQueryable<Product> Products { get { return _ProductRepository.GetAll(); } } public async Task<Product> CreateProduct(Product input) { var result = await _ProductRepository.InsertAsync(input); await _unitOfWorkManager.Current.SaveChangesAsync(); return result; } #endregion } 

它将在此行引发错误:

await _adManager.Ads.Where(p => p.Name == input.Name).FirstOrDefaultAsync();

但是,如果我改用它,它将起作用:

await _adManager.AdRepository.FirstOrDefaultAsync(p => p.Name == input.Name);

另外,我在上面的代码_unitOfWorkManager.Current作为null
有什么建议吗?

UnitOfWork属性

添加[UnitOfWork]属性并使其成为virtual方法:

[UnitOfWork]
public virtual async Task<ProductDto> CreateProduct(CreateProductInput input)
{
    var existing = await _productManager.Products
        .Where(p => p.Name == input.Name)
        .FirstOrDefaultAsync();

    // ...
}
[UnitOfWork]
public virtual async Task<Product> CreateProduct(Product input)
{
    var result = await _ProductRepository.InsertAsync(input);
    await _unitOfWorkManager.Current.SaveChangesAsync();
    return result;
}

请参阅: UnitOfWork属性限制

您可以将UnitOfWork属性用于:

  • 在接口上使用的类的所有公共公共虚拟方法(例如在服务接口上使用的应用程序服务)。
  • 用于自注入类的所有公共虚拟方法(如MVC控制器Web API控制器 )。
  • 所有受保护的虚拟方法。

IUnitOfWorkManager

您可以注入IUnitOfWorkManager来显式启动UnitOfWork

public async Task<Product> CreateProduct(Product input)
{
    using (var uow = _unitOfWorkManager.Begin())
    {
        var result = await _ProductRepository.InsertAsync(input);
        await _unitOfWorkManager.Current.SaveChangesAsync();

        await uow.CompleteAsync();

        return result;
    }
}

通过为我的appservice创建接口,然后在测试项目中解决此接口,可以解决我的问题。

感谢aaron的建议,但是在我的每个应用程序服务中使用uniofwork会很复杂。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM