Moq:在不返回值的方法上调用方法后的回调

Kev*_*aft 4 c# unit-testing moq

我目前正在使用 Moq 库进行单元测试。Moq 使我能够在模拟对象上的方法调用之前之后注册回调如下所示:

Mock<IMyClass> mock = new Mock<IMyClass>();
mock.Setup(o => o.MyMethod())
  .Callback(() => Console.WriteLine("BEFORE!"))
  .Returns(true)
  .Callback(() => Console.WriteLine("AFTER!"));
Run Code Online (Sandbox Code Playgroud)

但是,如果MyMethod不返回值(即它有一个void返回类型),那么我只能像这样设置一个回调:

mock.Setup(o => o.MyMethod())
  .Callback(() => Console.WriteLine("BEFORE!"));
Run Code Online (Sandbox Code Playgroud)

如代码中所述,此回调在调用方法之前发生。似乎没有任何其他选项可以调用方法指定第二个回调。

这可能吗?文档中似乎没有关于它的任何内容。我错过了什么吗?

Eri*_*rik 5

这是不可能的。

的返回值Callback是IReturnsThrows,这是的组合IReturns与接口Returns方法,以及IThrows与接口Throws方法。你可以跟在 a 后面ReturnsCallback因为 的返回值Returnsis IReturnResultwhich implements ICallback

你到底想完成什么?您示例中的回调实际上并没有在调用方法之前和之后发生,它们只是在调用方法时按步骤顺序执行。您的 before 回调在计算返回值之前执行,然后您的 after 回调在此之后完成。连续执行两个回调是没有意义的,因为您可以将它们组合成一个回调。

  • 是的,回调发生在“Returns”语句计算之前和之后(请参阅示例中回调中“Console.WriteLine”调用中的文本)。它们是调用方法时执行的步骤。当使用模拟对象的代码调用“someObj.MyMethod()”时,实际上没有调用方法之前/之后,这就是方法调用。 (2认同)
  • @rsenna,不,我不同意。“Returns”方法本身并不是方法体,当您放置“Callback”、“Returns”、“Throws”等时,这些“是”模拟方法调用的实现。从调用方法的代码的角度来看,所有这些事情都是作为方法调用的一部分发生的。在方法调用之前或之后发生的事情不属于该方法调用的一部分,而是在调用之外完成的。 (2认同)