最小起订量:无效的回调.具有参数的方法上的设置无法调用具有参数的回调

最小起订量:无效的回调.具有参数的方法上的设置无法调用具有参数的回调

问题描述:

我正在尝试使用最小起订量来编写单元测试.这是我的单元测试代码

I am trying to use moq to write a unit test. Here is my unit test code

        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.

SendCommand takes an object and optional boolean parameter. And MyCommand derives from ICommand.

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

测试运行时,我看到了错误

When the test runs, I see the error

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

我想检查消息的内容是否是我发送的内容.我在论坛上进行了搜索,发现此问题有两个不同的变体,但这些变体没有帮助.任何帮助,我们将不胜感激.

I want to check if the content of the message is what I sent in. I searched the forum and found a couple of different variations of this issue, but those didn't help. Any help is greatly appreciated.

您需要使用方法期望的特定类型来调用Callback的泛型重载.以下应该可以工作:

You need to call the generic overload of Callback with the specific types expected by the method. The following should work:

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调用不符合条件,也可以继续进行,然后在事后对其进行验证,则可以改为执行此操作(在调用测试的方法之后):

If the assertions fail in the callback then the test fails immediately, so the call to Verifiable() (and presumably the subsequent call to Verify()) seems to be redundant. If you want to allow the mocked Send invocation to proceed even if it does not meet the criteria and then verify it after the fact, then you can do this instead (after the tested method is invoked):

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());