簡體   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