我如何用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);
是的,我同意@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
方法,在那里添加一些测试。