我对与单元测试和模拟有关的概念很新。如果这是一个愚蠢的问题,或者我想出了解这些概念的例子,请原谅我的无知。我们说我有以下界面
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。有人可以告诉我如何实现这个目标的任何例子吗?
答案 0 :(得分: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);
}