使用 Moq 验证是否已调用 void 方法

Nov*_*orm 3 c# unit-testing moq

我有一个班级负责制作用于导出的 PPT 幻灯片。为了对此进行单元测试,我创建了一个接口,以便可以使用 Moq 进行模拟;到目前为止一切都很好。然而,当我尝试测试我的方法是否已被调用时,我遇到了困难。这是一个 void 方法,所以此时我只想知道该方法已被命中。

这是我的界面:

interface IPowerpointExporter
{
    void AddSlides(int amount);

    void setTitle(string title);
}
Run Code Online (Sandbox Code Playgroud)

这是我的单元测试:

[TestMethod]
public void testPPTObject()
{
    var mockPPT = new Mock<IPowerpointExporter>();
    mockPPT.Setup(m => m.AddSlides(1)).Verifiable();
    mockPPT.Object.AddSlides(1);
    mockPPT.VerifyAll();
}
Run Code Online (Sandbox Code Playgroud)

然而,当我打电话时,AddSlides()我得到了一个GeneratorException。对此的解释是我的 IPowerpointExporter 无法访问。我有一种感觉,这是因为我正在尝试调用接口上的方法,尽管我不确定,因为mockPPT.Object.AddSlides();此时我已经得到了我的对象。

请注意,我还尝试了以下尝试使用实际对象而不是 Interface.Object。这也给出了同样的例外:

[TestMethod]
public void testPPTObject()
{
    var mockPPT = new Mock<IPowerpointExporter>();
    mockPPT.Setup(m => m.AddSlides(1)).Verifiable();

    ExportPowerPoint temp = (ExportPowerPoint)mockPPT.Object;
    temp.AddSlides(1);
    mockPPT.VerifyAll();
}
Run Code Online (Sandbox Code Playgroud)

使用 Moq 如何检查我的方法是否已被调用?我上面所做的事情正确吗?

Pat*_*irk 5

public您可能会遇到该异常,因为您的接口对 Moq 程序集不可见,或者以其他方式可见。请参阅此问题来解决该问题。

如果这只是帮助您学习 Moq 的虚拟代码,那么就不要再阅读了。


然而,如果您认为这是一个有价值的实际测试,那么您还有其他更根本的问题。在您的第一个示例中,您完全没有执行任何操作来测试代码! 让我们逐行浏览一下:

var mockPPT = new Mock<IPowerpointExporter>();
Run Code Online (Sandbox Code Playgroud)

您创建了界面的模拟IPowerpointExporter,到目前为止一切顺利。

mockPPT.Setup(m => m.AddSlides(1)).Verifiable();
Run Code Online (Sandbox Code Playgroud)

您告诉模拟期望调用它的AddSlide方法,参数为1,并且该方法可以被验证。到目前为止没有问题。

mockPPT.Object.AddSlides(1);
Run Code Online (Sandbox Code Playgroud)

但这就是它偏离轨道的地方。您只需在模拟上调用该方法,与上面刚刚设置的方法相同。该Object属性是一个虚拟对象,它只能执行其设置要做的事情,与您的实际实现无关

mockPPT.VerifyAll();
Run Code Online (Sandbox Code Playgroud)

现在您已验证是否调用了所有可验证的方法。您在此测试中所做的只是验证 Moq 是否有效;你的代码从未被触及。

现在让我们看看第二个示例中更改后的代码:

ExportPowerPoint temp = (ExportPowerPoint)mockPPT.Object;
temp.AddSlides(1);
Run Code Online (Sandbox Code Playgroud)

那个演员阵容永远不会成功。Object属性只是一些代理(实际上是动态类型),由 Moq 生成,它对它所模拟的接口的任何具体实现一无所知。