2016-02-29 64 views
0

我有一个类负责构建用于导出的PPT幻灯片。为了进行单元测试,我创建了一个接口,以便使用Moq进行模拟;迄今为止都很棒。然而,当我试图测试我的方法已被调用时,我遇到了困难。这是一个无效的方法,所以在这一点上,我只想知道该方法已被击中。验证是否使用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(); 
} 

然而,当我来电话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(); 
} 

使用起订量我怎么能确认我的方法被调用?我正在做的是正确的路线吗?

+1

看来你正在测试你的模拟。您应该使用IPowerpointExporter测试代码,并在那里验证(模拟)接口上的方法被称为 – andreasnico

回答

3

您可能会遇到此异常,因为您的界面不是public,或者对Moq组件可见。请参阅this question来解决该问题。

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


但是,如果这是一个您认为具有价值的实际测试,那么您还有其他更基本的问题。在你的第一个例子中,你完全没有办法测试你的代码!让我们通过它,一行行:

var mockPPT = new Mock<IPowerpointExporter>(); 

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

mockPPT.Setup(m => m.AddSlides(1)).Verifiable(); 

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

mockPPT.Object.AddSlides(1); 

但是,这里是它脱轨的地方。你只是在你的模拟中调用该方法,就像你刚刚设置的那个一样。 Object属性是虚拟对象,它只能做它被设置的事情,而与你的实际实现没有任何联系!

mockPPT.VerifyAll(); 

现在您验证了您调用了所有可验证的方法。你在这个测试中做的所有事情都证明了Moq的工作原理。你的代码从未被触及。

让我们来看看改变的代码在你的第二个例子,现在:

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

以为蒙上不会有任何效果。Object属性只是一些代理(实际上是一种动态类型),由Moq生成,对于它正在嘲讽的接口的任何具体实现一无所知。

+0

为了让自己回到正确的轨道上,我该如何测试方法调用已被命中?只需创建一个ExportPowerPoint对象并调用AddSlides()方法就足以触发VerifyAll()? – Novastorm

+0

你的第一个例子将做你想做的事(如果你修复了你的界面的可见性),但正如我所说的,除了学习Moq之外,它是一个毫无价值的测试。 –

0

发生此异常是因为Moq不能访问IPowerpointExporter接口。

你可以让你IPowerpointExporter接口public和测试完美运行:

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

但是,当你需要做测试,以非公开的类型,可以使用InternalsVisibleTo属性,在装配,使各类可见起订量。

[assembly:InternalsVisibleTo("DynamicProxyGenAssembly2")] 
+0

只是被帕特里克的答案殴打,将界面改为公开是要走的路 – Novastorm