2016-12-01 58 views
2

我對與單元測試和嘲笑相關的概念頗爲陌生。請原諒我的無知,如果它是一個愚蠢的問題或我想出來瞭解這些概念的例子。假設我有以下接口將嘲諷概念應用於實際單元測試時,腦凍結

public interface IMyService 
{ 
    OrderConfirmation ProcessOrder(Order order); 
} 

Order和OrderConfirmation類定義如下。

public class Order 
{ 
    public int OrderId { get; set; } 
    public int CustomerId { get; set; } 
    public List<Product> Products { get; set; } 
} 

public class Product 
{ 
    public int ProductId { get; set; } 
    public string ProductName { get; set; } 
    public int Price { get; set; } 
} 

public class OrderConfirmation 
{ 
    public int OrderConfirmationId { get; set; } 
    public int OrderId { get; set; } 
    public Shipment ShipmentDetails { get; set; } 
} 

public class Shipment 
{ 
    public int ShipmentId { get; set; } 
    public DateTime ShipmentDate { get; set; } 
    public int Cost { get; set; } 
} 

實現IMyService接口的類的實現如下。這裏的關鍵是它依賴於通過構造函數注入的數據提供者。

public class MyService : IMyService 

{ 
    private IDataProvider DataProvider; 

    public MyService(IDataProvider dataProvider) 
    { 
     DataProvider = dataProvider; 
    } 

    public OrderConfirmation ProcessOrder(Order request) 
    { 
     // bunch of operations here including calling various methods of DataProvider to save/retrieve data from databse. 

    } 
} 

IDataProvider接口有一堆操作來存儲/檢索數據庫中的數據。

public interface IDataProvider 

{ 
    List<Product> GetAllProducts(); 
    int CreateOrder(int customerId, List<Product> products); 
    int CreateOrderConfirmation(int OrderConfirmationId, int orderId); 
    void UpdateListOfAvailableProducts(List<Product> products); 

} 

爲了測試對ProcessOrder方法,看來我將不得不以某種方式嘲弄IDataProvider接口的所有方法,但我真搞不清楚如何提供嘲笑實現(使用)最小起訂量。有人可以告訴我有關如何完成此任務的任何示例嗎?

+1

https://github.com/Moq/moq4/wiki/Quickstart – Nkosi

+1

顯示被測方法,IDataProvider接口是如何行使。 – Nkosi

回答

1

下面是許多假設示例中的一個,它是如何模擬數據提供程序依賴關係的。 但是請注意,在沒有看到測試方法的真實實施的情況下說些什麼是非常含糊的。 HTH

[TestMethod] 
public void ProcessOrder_WhenSomeTestedCondition_ThenCertainExpectedResult() 
{ 
    // Arrange 
    OrderConfirmation expectedResult = new OrderConfirmation(); // Set expected result here 
    Order fakeRequest = new Order(); 
    List<Product> fakeProducts = new List<Product>(); 
    int fakeCreateOrderResult = 123; 
    int fakeCreateOrderConfirmationResult = 456; 

    // This is the mocked dependency 
    Mock<IDataProvider> dataProviderMock = new Mock<IDataProvider>(); 

    // Here the method is setup so it returns some fake products 
    dataProviderMock.Setup(dp => dp.GetAllProducts()) 
     .Returns(fakeProducts); 

    // Here the method is setup so it returns some fake result 
    dataProviderMock.Setup(dp => dp.CreateOrder(It.IsAny<int>(), It.IsAny<List<Product>>())) 
     .Returns(fakeCreateOrderResult); 

    // Here the method is setup so it returns some fake result 
    dataProviderMock.Setup(dp => dp.CreateOrderConfirmation(It.IsAny<int>(), It.IsAny<int>())) 
     .Returns(fakeCreateOrderConfirmationResult); 

    // Here the method UpdateListOfAvailableProducts returns void so 
    // an example using callback is shouwing how the provided list of new products 
    // could update the existing ones 
    dataProviderMock.Setup(dp => dp.UpdateListOfAvailableProducts(
     new List<Product> { new Product {Price = 100, ProductId = 1, ProductName = "Product_X"}})) 
     .Callback<List<Product>>(np => 
     { 
      fakeProducts.AddRange(np); 
     }); 

    // This is class under test which receives the mocked data provider object 
    MyService service = new MyService(dataProviderMock.Object); 

    // Act 
    // Here the tested method is executed 
    OrderConfirmation actualResult = service.ProcessOrder(fakeRequest); 

    // Assert 
    // Compare expected and actual results 
    Assert.AreEqual(expectedResult.OrderId, actualResult.OrderId); 
}