UnitTest -issue来自mock的测试方法

时间:2014-09-16 10:13:32

标签: c# unit-testing tdd

我正在使用一个具有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行并直接按下我的方法,它就可以了!但我想使用模拟。

我做错了什么?

我使用了错误的方法吗?

2 个答案:

答案 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);
}

愚蠢(简单)的测试导致了简单的生产代码,这正是你想要的。

尽可能避免对调用的模拟和断言采取严格的行为,因为这会使测试变得脆弱。