Moq Verify无法匹配对已更改对象的重复方法调用

时间:2014-02-20 11:05:46

标签: callback installation moq verify

我需要测试存储库Save()方法是否使用相同的对象调用两次,但是在调用之间对象的属性已经更改。

SUT代码归结为:

        Person person = _repos.Load(name);

        person.Age = age1;
        _repos.Save(person);
        person.Age = age2;
        _repos.Save(person);

UT代码是:

        // Arrange
        Mock<IRepository> repo = new Mock<IRepository>();

        repo.Setup(m => m.Load(It.IsAny<String>())).Returns(new Person { Name = "Jim", Age = 20 });
        repo.Setup(m => m.Save(It.Is<Person>(p => p.Age == 21))).Callback(() =>
            {
                Debug.Print("Age = 21");
            });
        repo.Setup(m => m.Save(It.Is<Person>(p => p.Age == 22))).Callback(() =>
            {
                Debug.Print("Age = 22");
            }).Returns(1);
        var service = new ABCService(repo.Object);

        // Act
        service.ChangeAge("Jim", 21, 22);

        // Assert
        repo.Verify(m => m.Save(It.Is<Person>(p => p.Age == 22)), Times.Once); 
        repo.Verify(m => m.Save(It.Is<Person>(p => p.Age == 21)), Times.Once);

执行测试时,会按预期命中两个单独的回调。但是,第一次验证失败是因为Moq认为它被调用了两次,而第二次验证失败了,因为没有调用。

在方法调用时,似乎不保留Save()调用中使用的Person对象参数的属性。相反,它似乎只是持有对Person参数的引用并在所有调用后检查其属性。

有没有办法绕过这个?我唯一能想到的是在多个Setup.Callbacks中取代对象属性(替换Debug.Print语句)。但是,由于Save()方法没有任何内容可以返回,所以最好没有.Setups。

1 个答案:

答案 0 :(得分:0)

我想说这是Moq中的一个错误,您可以在github上报告: https://github.com/Moq/moq4

但是我会通过跳过两次调用VerifyAll()验证来解决这个问题。 与Patrick Qurik指出的the solved issue类似。

  // Arrange
  Mock<IRepository> repo = new Mock<IRepository>();

  repo.Setup(m => m.Load(It.IsAny<String>())).Returns(new Person { Name = "Jim", Age = 20 });
  repo.Setup(m => m.Save(It.Is<Person>(p => p.Age == 21)));
  repo.Setup(m => m.Save(It.Is<Person>(p => p.Age == 22)));

  var service = new ABCService(repo.Object);

  // Act
  service.ChangeAge("Jim", 21, 22);

  // Assert
  repo.VerifyAll();