我如何用mock来做这个集成测试单元测试?

本文关键字:集成测试 单元测试 何用 mock | 更新日期: 2023-09-27 18:13:49

我是新手。我有一个集成测试,我想改变为单元测试。我知道我必须模拟balancePositiveCalculator,因为它与classUnderTest合作依赖,但我不确定如何在这里模拟,所以我只测试classUnderTest。我是否必须创建模拟的balancePositiveCalculator和设置参数和罐头返回,然后使用模拟对象方法来计算成本。feesandinterest ?

[TestMethod]
public void Calculate_VirtualSaving_PositiveSaving()
{
    var balance = 100M;
    var monthlyRepayment = 20M;
    var currentInterestRate = 18.9M;
    var savingsExpected = 24M;
    var fakeCreditCard = new CreditCardGold { Money = 15 };
    var currentFees = _classUnderTest.Calculate(balance, currentInterestRate, monthlyRepayment, 0M, 1);
    var balancePositiveCalculator = new BalancePositiveCalculator(_classUnderTest);
    var costs = balancePositiveCalculator.Calculate(fakeCreditCard, balance, monthlyRepayment);
    var savingsActual = currentFees.InterestPaid - costs.FeesAndInterest;
    savingsActual.ShouldBeInRange(savingsExpected - 1M, savingsExpected + 1M);
}
编辑(我试过了)。这是正确的方法吗?
var fakeCalculatorResult = new CalculatorResult
{
    FeesAndInterest = 12
};
var mockBalancePositiveCalculator = new Mock<IBalancePositiveCalculator>();
mockBalancePositiveCalculator
    .Setup(x => x.Calculate(It.IsAny<CreditCardGold>(), It.IsAny<decimal>(), It.IsAny<decimal>()))
    .Returns(fakeCalculatorResult);
// act
var currentCreditCardCost = _classUnderTest.Calculate(balance, currentInterestRate, monthlyRepayment, 0M, 1);
var costs = mockBalancePositiveCalculator .Object.Calculate(It.IsAny<CreditCardGold>(), It.IsAny<decimal>(), It.IsAny<decimal>());
var savingsActual = currentCreditCardCost.InterestPaid - costs.FeesAndInterest;
// assert      
savingsActual.ShouldBeInRange(savingsExpected - 5M, savingsExpected + 5M);

我如何用mock来做这个集成测试单元测试?

是的,我同意@Lee Campbell的观点——你的依赖关系是前后颠倒的。你要做的是模拟类中的任何依赖,然后将它们注入。这就是IOC容器在编写单元可测试代码时如此流行的原因。"_classUnderTest"的实现没有依赖关系,因此可以自己进行单元测试。然而"BalancePositiveCalculator"依赖于"_classUnderTest",这就是你想模拟并注入"BalancePositiveCalculator"的内容。

测试将看起来像下面这样:

    [TestMethod]
    public void BalancePositiveCalculator()
    {
        var balance = 100M;
        var monthlyRepayment = 20M;
        var currentInterestRate = 18.9M;
        var savingsExpected = 24M;
        var fakeCreditCard = new CreditCardGold { Money = 15 };
        var classUnderTestMock = new Mock<IClassUnderTest>();
        classUnderTestMock.Setup(
            test =>
                test.Calculate(It.IsAny<decimal>(), 
                    It.IsAny<decimal>(), 
                    It.IsAny<decimal>(), 
                    It.IsAny<decimal>(),
                    It.IsAny<decimal>()))
            .Returns(new ClassUnderTest());
        classUnderTestMock.Setup(test => test.InterestPaid).Returns(balance);
        var balancePositiveCalculator = new BalancePositiveCalculator(classUnderTestMock.Object);
        var costs = balancePositiveCalculator.Calculate(fakeCreditCard, balance, monthlyRepayment);
        var savingsActual = classUnderTestMock.Object.InterestPaid - costs.FeesAndInterest;
        savingsActual.ShouldBeInRange(savingsExpected - 1M, savingsExpected + 1M);
    }

这也意味着你显然会有一个像这样的接口:

public interface IClassUnderTest
{
    ClassUnderTest Calculate(decimal balance, 
        decimal currentInterestRate, 
        decimal monthlyRepayment, 
        decimal num1, 
        decimal num2);
    decimal InterestPaid { get; }
}

由于您对BalancePositiveCalculator所做的一切都是创建一个从另一个金额中减去的金额,因此您可以完全省略它。实际上,您只测试_classUnderTest.Calculate,更确切地说,测试其返回值的InterestPaid属性。

我更愿意为返回值的其他属性添加一些Assert s。

对于BalancePositiveCalculator.Calculate方法,在那里添加一些测试。