我正在使用一个具有void方法的接口的类看起来像这个女巫现在是完全可行的方法:
public void SellGivenQuantityOfProduct(Product product, int quantity)
{
product.StockQuantity = product.StockQuantity - quantity;
}
但是使用TDD方式,我开始在下面这样做,但计算从未在我的测试方法中发生
[TestMethod]
public void Can_Sell_Given_Quantity_Of_Single_Products_Stock_Quantity()
{
var mock = new Mock<ISellBuyPipeLine>();
mock.Setup(o => o.Products).Returns(new Product[]
{
new Product() {ArticleNr = 87, StockQuantity = 10}
});
var product = mock.Object.Products.First();
var choosenProductToSell = new SellBuyProduct() {Product = product, Quantity = 5};
mock.Object.SellGivenQuantityOfProduct(product, choosenProductToSell.Quantity);
/*var test = new SellBuyPipeLine();
test.SellGivenQuantityOfProduct(product, choosenProductToSell.Quantity);*/
int expectedSellValue = product.StockQuantity;
Assert.AreEqual(5, expectedSellValue);
}
如果我正在使用outcommented行并直接按下我的方法,它就可以了!但我想使用模拟。
我做错了什么?
我使用了错误的方法吗?
答案 0 :(得分:3)
如果要测试实现,请测试实现。模拟对象的方法不包含实现。
您可能想要模拟Product
,使测试方法看起来像这样:
public void Can_Sell_Given_Quantity_Of_Single_Products_Stock_Quantity()
{
// Arrange
int stockQuantity = 10;
int quantityToSell = 4;
int newQuantity = 6;
var productMock = new Mock<Product>(MockBehavior.Strict);
productMock.SetupGet(p => p.StockQuantity).Returns(stockQuantity);
productMock.SetupSet(p => p.StockQuantity = newQuantity);
var classUnderTest = new SellBuyPipeLine();
// Act
test.SellGivenQuantityOfProduct(product, quantityToSell);
// Assert
productMock.VerifySet(p => p.StockQuantity, Times.Once());
}
您可以不用,因为产品不包含任何逻辑,在这种情况下,只需实例化new Product
并断言其StockQuantity
等于newQuantity
;
答案 1 :(得分:2)
除非您的Product
类包含实际的业务逻辑,否则不要嘲笑它。当你可以随时编写测试时,我建议假装是愚蠢的。
[TestMethod]
public void Can_Sell_Given_Quantity_Of_Single_Products_Stock_Quantity()
{
var product = new Product { ArticleNr = 87, StockQuantity = 10 };
var pipeline = new SellBuyPipeLine();
pipeline.SellGivenQuantityOfProduct(product, 5);
Assert.AreEqual(5, product.StockQuantity);
}
愚蠢(简单)的测试导致了简单的生产代码,这正是你想要的。
尽可能避免对调用的模拟和断言采取严格的行为,因为这会使测试变得脆弱。