2016-12-01 4 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インターフェイスのすべてのメソッドを模擬しなければならないようですが、私はMOQ(使用)を嘲笑実装を提供する方法については本当に混乱しています。誰かが私にこれを達成する方法の例を教えてもらえますか?

+1

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

+1

はIDataProviderインターフェイスが行使されたか、テスト対象のメソッドを表示します。 – Nkosi

答えて

1

ここでは、データプロバイダの依存関係の模様がどのように見えるかを示す多くの仮定的な例の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); 
} 
関連する問題