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

C# 验证是否已使用Moq调用void方法,c#,unit-testing,moq,C#,Unit Testing,Moq,我有一个班,负责制作PPT幻灯片以供导出。为了进行单元测试,我创建了一个接口,这样就可以使用Moq进行模拟;到目前为止一切都很好。然而,当我尝试测试我的方法是否被调用时,我遇到了困难。这是一个无效的方法,所以在这一点上,我只想知道该方法已命中 这是我的界面: interface IPowerpointExporter { void AddSlides(int amount); void setTitle(string title); } 下面是我的单元测试: [TestMet

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

这是我的界面:

interface IPowerpointExporter
{
    void AddSlides(int amount);

    void setTitle(string title);
}
下面是我的单元测试:

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

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

您可能会遇到这种异常,因为您的界面不是
公共的,或者对Moq程序集不可见。请务必解决这个问题

如果这只是帮助您学习Moq的伪代码,那么请不要阅读更多内容


然而,如果这是一个您认为有价值的实际测试,那么您还有其他更基本的问题。在第一个示例中,您完全没有做任何事情来测试代码让我们一行一行地看一遍:

var mockPPT = new Mock<IPowerpointExporter>();
您告诉mock希望调用它的
AddSlide
方法,参数为
1
,并且可以验证该方法。到目前为止没有问题

mockPPT.Object.AddSlides(1);
但这就是它偏离轨道的地方。您只是在模拟上调用该方法,与上面设置的方法相同。
对象
属性是一个虚拟对象,它只能执行设置时要执行的操作,与实际实现没有任何关系

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

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

ExportPowerPoint temp = (ExportPowerPoint)mockPPT.Object;
temp.AddSlides(1);

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

发生此异常是因为Moq无法访问
IPowerpointExporter
接口

您可以将您的
IPowerpointExporter
界面
公开
,并完美地运行测试:

public interface IPowerpointExporter
{
    void AddSlides(int amount);

    void setTitle(string title);
}

....

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

看来你在测试你的模拟。您应该使用IPowerpointExporter测试代码,并在那里验证(模拟)接口上的方法是否被调用,以使自己回到正确的轨道上如何测试方法调用是否被命中?仅仅创建一个ExportPowerPoint对象并对其调用AddSlides()方法就足以触发VerifyAll()?您的第一个示例将实现您想要的功能(如果您修复了界面的可见性),但正如我所说的,除了学习Moq之外,这是一个毫无价值的测试。
mockPPT.VerifyAll();
ExportPowerPoint temp = (ExportPowerPoint)mockPPT.Object;
temp.AddSlides(1);
public interface IPowerpointExporter
{
    void AddSlides(int amount);

    void setTitle(string title);
}

....

[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();
}
[assembly:InternalsVisibleTo("DynamicProxyGenAssembly2")]