MOQ - 验证增量属性调用

时间:2012-05-14 10:43:58

标签: c# .net unit-testing tdd moq

以下代码段最能说明我要实现的目标:

[Test]
public void ReplayGoalTeamATest()
{
    var stateMachineMock = new Mock<IIceHockeyOddsStateMachine>();

    new IceHockeyActionLogRecord { Event = "goal", Team = "A"}.Replay(stateMachineMock.Object);

    stateMachineMock.Verify(s=>s.TeamAScore++); //Syntax error
}

3 个答案:

答案 0 :(得分:2)

如果您在IIceHockeyOddsStateMachine界面上同时拥有getter和setter,则可以验证该值是否增加如下:

var stateMachineMock = new Mock<IIceHockeyOddsStateMachine>();

stateMachineMock.SetupAllProperties();

stateMachineMock.Object.TeamAScore = 0;

new IceHockeyActionLogRecord { Event = "goal", Team = "A"}.Replay(stateMachineMock.Object);

Assert.That(stateMachineMock.Object.TeamAScore, Is.EqualTo(1));

答案 1 :(得分:1)

执行s.TeamAScore++时,您有两种不同的操作,您应该设置并验证这些操作。第一个操作是从您的依赖项中获取当前分数,第二个操作是设置新分数:

int score = stateMachine.TeamAScore;
// other staff
stateMachine.TeamAScore = score + 1;

所以,我会明确定义这种与依赖的交互:

// Arrange
Mock<IIceHockeyOddsStateMachine> stateMachineMock = new Mock<IIceHockeyOddsStateMachine>();
stateMachineMock.SetupGet(s => s.TeamAScore).Returns(0);
IceHockeyActionLogRecord record = new IceHockeyActionLogRecord { Event = "goal", Team = "A"};
// Act
record.Replay(stateMachineMock.Object);
// Assert
stateMachineMock.VerifySet(s => s.TeamAScore = 1); 

在这种情况下,您正在测试IceHockeyActionLogRecord,它与依赖关系的交互方式。测试成为对象之间交互的规范。

当您验证TeamAScore值时,您正在测试模拟实现。使用Callback也会测试你的代码,而不是测试对象之间的交互。

另外,我会在测试中给出魔术数字的名称,甚至提供参数:

[TestCase(0, 1)]
[TestCase(50, 51)]
public void ShouldIncrementTeamScore(int initialScore, int expectedScore)
{
    var stateMachineMock = new Mock<IIceHockeyOddsStateMachine>();
    stateMachineMock.SetupGet(s => s.TeamAScore).Returns(initialScore);
    IceHockeyActionLogRecord foo = new IceHockeyActionLogRecord();
    foo.Replay(stateMachineMock.Object);
    stateMachineMock.VerifySet(s => s.TeamAScore = expectedScore);            
}

更新:如果您的界面没有属性的getter,那么只需修改Arrange部分的测试(不要设置属性getter调用):

// Arrange
var stateMachineMock = new Mock<IIceHockeyOddsStateMachine>();
var record = new IceHockeyActionLogRecord { Event = "goal", Team = "A"};
// Act
record.Replay(stateMachineMock.Object);
// Assert
stateMachineMock.VerifySet(s => s.TeamAScore = 1); 

答案 2 :(得分:0)

您是否尝试过使用.CallBack()方法?不确定验证是否支持上述实施