2014-03-25 40 views
2

我正在對我的Service layer class(ProductService)之一進行單元測試。該層將DI工具用於controller class(ProductController)之一。對於ProductController單元測試,已經有一個單元測試類ProductControllerTest。如何在單元測試中使用moq對象?

但對於單元測試ProductController的的服務層(ProductService),我已創建了一個新的單元測試類(ProductServiceTest)

但我不知道我是否應該創建一個新的單元測試類來做服務層單元測試與否。

此外,我想知道單元測試中的DI(Dependency Injection) and Mocking(MOQ object)的概念。指在何處使用MOQ進行單元測試以及何時需要使用?

我已經寫了ProductService的一個action方法的單元測試代碼,並且我想知道它是否正確?

下面是一塊的操作方法代碼: -

public class ProductService : IProductService 
{ 
    private readonly IProductDal<Product> _productDal; 
    private readonly IUserDal<Users> _userDal; 

    public ProductService(IProductDal<Product> ProductDAL) 
    { 
     _productDal = ProductDAL; 
    } 


    public List<ProductDto> GetProducts(string SearchInName, string SearchInDescription) 
    { 
      List<ProductDto> productList = new List<ProductDto>(); 
      foreach (Product product in _productDal.GetProducts(SearchInName, SearchInDescription)) 
      { 
       productList.Add(Adapter.AdaptOmToDto(product)); 
      } 
      return productList; 
    } 
} 

下面是一塊的單元測試(ProductServiceTest)類的代碼: -

[TestMethod] 
    public void GetProductsTest() 
    { 
     var productList = new List<ProductDto>(); 

     // Arrrange    
     var Name = "CreateSave"; 
     var Description = "CreateSave"; 

     // Act 
     List<ProductDto> output = _productService.GetProducts(Name, Description); 

     // Assert  
     Assert.IsNotNull(output); 
     Assert.IsInstanceOfType(output, typeof(List<ProductDto>)); 
    } 

任何一個可以建議我的單元測試這種方法的最好方法是什麼?

+0

嗨,轉到此鏈接[MSDN](http://msdn.microsoft.com/zh-cn/library/ff650441.aspx)我希望它能幫助你 – 2014-03-25 07:50:04

回答

6

我也想知道DI(依賴注入)和嘲諷(MOQ對象)的單元測試

依賴注入是我們使我們的應用程序堅持Dependency Inversion Principle的方式,其中指出,概念高級模塊不應該依賴於低級模塊 - 兩者都應該依賴於抽象。根據抽象的不同,可以使系統中的單元低耦合,並且可以將抽象依賴性的任何實現賦予依賴類。這裏談到的部分涉及到單元測試 - 你可以給嘲笑執行的依賴,這將讓你驗證行爲(見Mocks Aren't Stubs文章)單元的測試。

您已經通過使您ProductService依賴於抽象的工作做得很好,並且使用DI注入抽象實施服務。你需要測試服務的行爲注入嘲笑實現抽象的關係,建立ProductService和模擬之間預期的相互作用是什麼:

ProductService _productService; 
Mock<IProductDal<Product>> _productDalMock; 

[TestInitialize] 
public void Setup() 
{ 
    // create mock of dependency and pass mocked object to service 
    _productDalMock = new Mock<IProductDal<Product>>(); 
    _productService = new ProductService(productDalMock.Object); 
} 

[TestMethod] 
public void ShouldNotReturnDtosWhenProductsNotFound() 
{ 
    // Arrrange 
    var name = "CreateSave"; 
    var description = "CreateSave"; 
    // setup mocked dal to return empty list of products 
    // when name and description passed to GetProducts method 
    _productDalMock.Setup(d => d.GetProducts(name, description)) 
        .Returns(new List<Product>()); 

    // Act 
    List<ProductDto> actual = _productService.GetProducts(name, description); 

    // Assert 
    Assert.False(actual.Any()); 
    // verify all setups of mocked dal were called by service 
    _productDalMock.VerifyAll(); 
} 

如您在測試中看到上面,你可以檢查產品服務是否調用的依賴正確的參數,並且你可以設置哪些數據應該依賴返回服務。對於下一次測試,您可以設置模擬以返回預定義產品的列表。然後你會驗證服務是否返回了合適的dtos。

+0

謝謝你的建議Sergey.But我想知道當我們在服務類構造函數中傳遞moq對象時,我們能夠從DAL類中獲取記錄嗎? 如你所知,我們有通MOQ反對構造函數,並在這種情況下,我沒有得到我們的「實際」對象中的任何記錄。我調試了代碼,得到的結果是,一旦控件進入DAL類,同時調用GetProducts方法,DAL對象只是返回不提取記錄。 – Pawan

+0

@Pawan你可以在你的'實際'對象中得到完全相同的記錄,你設置返回。如果你設置模擬返回空列表,它將返回空列表服務。如果你會提供一些其他列表'.Returns(新名單 {新產品(),新產品()})'那麼這兩個產品將返回服務 –

+0

謝謝你的答案。我明白了,我們使用moq對象而不是繞過真實對象並返回我們創建的對象。 但我想知道我們需要做什麼,如果有需要測試真實的物體?我們應該測試真實的物體嗎? – Pawan