【问题标题】:MOQ - Verify an increment property callMOQ - 验证增量属性调用
【发布时间】:2012-05-14 10:43:58
【问题描述】:

下面的代码 sn-p 最好地解释了我想要实现的目标:

[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
}

【问题讨论】:

  • 查看我的更新,了解属性只有 setter 的情况(顺便说一句,在这种情况下,使用方法比使用属性更好)
  • 太好了,谢谢。我从问题中删除了编辑测试,因为我意识到 TeamAScore++ 对于没有 getter 的道具是无稽之谈,我同意只有 setter 的道具应该是一种方法。

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


【解决方案1】:

如果您的 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));

【讨论】:

    【解决方案2】:

    当您执行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); 
    

    【讨论】:

      【解决方案3】:

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

      【讨论】:

      • 不,以上不编译。使用回调;问题依然存在,我该如何表达对 TeamAScore 将增加的期望?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-02-26
      • 1970-01-01
      • 1970-01-01
      • 2013-01-17
      • 1970-01-01
      • 2020-02-08
      • 2020-03-09
      相关资源
      最近更新 更多