37

我正在尝试使用 Moq 编写单元测试。这是我的单元测试代码:

var sender = new Mock<ICommandSender>();
sender.Setup(m => m.SendCommand(It.IsAny<MyCommand>(), false))
      .Callback(delegate(object o)
      {
          var msg = o as MyCommand;
          Assert.AreEqual(cmd.Id, msg.Id);
          Assert.AreEqual(cmd.Name, msg.Name);
      })
      .Verifiable();

SendCommand接受一个对象和可选的布尔参数。MyCommand 派生自 ICommand。

void SendCommand(ICommand commands, bool idFromContent = false);

测试运行时,我看到错误

System.ArgumentException : Invalid callback. Setup on method with parameters (ICommand,Boolean) cannot invoke callback with parameters (Object).

我想检查消息的内容是否是我发送的内容。我搜索了论坛,发现了这个问题的几个不同的变体,但这些都没有帮助。任何帮助是极大的赞赏。

4

1 回答 1

42

您需要使用方法预期的特定类型调用 Callback 的泛型重载。以下应该有效:

sender.Setup(x => x.SendCommand(It.IsAny<MyCommand>(), false))
      .Callback<ICommand, bool>((command, idFromContent) =>
          {
              var myCommand = command as MyCommand;
              Assert.That(myCommand, Is.Not.Null);
              Assert.That(myCommand.Id, Is.EqualTo(cmd.Id));
              Assert.That(myCommand.Name, Is.EqualTo(cmd.Name));
          })
      .Verifiable();

如果断言在回调中失败,那么测试将立即失败,因此对 Verifiable() 的调用(以及对 Verify() 的后续调用)似乎是多余的。如果您希望模拟的 Send 调用在不符合条件的情况下继续进行,然后在事后验证它,那么您可以改为执行此操作(在调用测试方法之后):

sender.Verify(x => x.SendCommand(It.Is<MyCommand>(c => 
    {
        Assert.That(c, Is.Not.Null);
        Assert.That(c.Id, Is.EqualTo(cmd.Id));
        Assert.That(c.Name, Is.EqualTo(cmd.Name));
        return true;
    }), false), Times.Once());
于 2013-09-21T01:32:37.277 回答