我正在编写一个单元测试用例,当第一笔付款成功并且第二笔付款失败时,我需要回滚第一笔付款。单元测试代码如下所示:
我已经为(1)编写了单元测试。 SO社区如何指导如何处理第2,3,4部分?
[TestMethod]
public void IfTheSecondPaymentFailsThenTheFirstPaymentShouldBeVoided()
{
//Arrange
var iPaymentMock = new Mock<IPaymentMock>();
var paymentSpecificationResponse = new PreregisteredAccountSpec();
iPaymentMock.Setup(
counter => counter.ProcessPayment
(
It.IsAny<Context>(),
It.IsAny<PreregisteredAccountSpec>(),
It.IsAny<Guid>())
).
Returns(paymentSpecificationResponse);
//Act
var twoPaymentProcessor = new TwoPaymentProcessor(iPaymentMock.Object);
twoPaymentProcessor.Submit();
//assert
iPaymentMock.Verify((
counter => counter.ProcessPaymentSpecification
(
It.IsAny<Context>(),
It.IsAny<PreregisteredAccountSpec>(),
It.IsAny<Guid>()
)
), Times.Once());
}
答案 0 :(得分:2)
看起来你想在模拟上使用SetupSequence
而不是Setup
。
这允许你做类似
iPaymentMock.SetupSequence(counter => counter.ProcessPayment
(
It.IsAny<Context>(),
It.IsAny<PreregisteredAccountSpec>(),
It.IsAny<Guid>())
)
.Returns(paymentSpecificationResponse)
.Throws(new Exception());
我可能有你想要的错误的细节但SetupSequence
允许你在模拟上有多个回报,但是调用顺序很重要。
答案 1 :(得分:0)
我不太确定如何处理2,3和4的测试,但是在回答标题中的一般问题时,可以通过在lamba中使用lamba从模拟的多次调用中获得不同的返回值。 Returns()
条款。
说我们有以下
public interface IPayment
{
Result ProcessPayment();
}
public class Result
{
public Result(int id)
{
Id = id;
}
public int Id { get; }
}
我们可以每次调用ProcessPayment()
返回不同的值,如下所示
[TestMethod]
public void DifferentResultsOnEachInvocation()
{
var results = new[] {
new Result(1),
new Result(2),
new Result(3)
};
var index = 0;
var mockPayment = new Mock<IPayment>();
mockPayment.Setup(mk => mk.ProcessPayment()).Returns(()=>results[index++]);
var res = mockPayment.Object.ProcessPayment();
Assert.AreEqual(1, res.Id);
res = mockPayment.Object.ProcessPayment();
Assert.AreEqual(2, res.Id);
res = mockPayment.Object.ProcessPayment();
Assert.AreEqual(3, res.Id);
}
如果设置只返回results[index++]
,则在设置时结晶,每次调用都返回数组的第一个元素。通过使它成为lamba,每次调用ProcessPayment()
时都会对其进行评估。