验证是否使用Moq调用了无效方法
我有一个类负责构建用于导出的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();
}
使用起订量我怎么能确认我的方法被调用?我正在做的是正确的路线吗?
您可能会遇到此异常,因为您的界面不是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生成,对于它正在嘲讽的接口的任何具体实现一无所知。
为了让自己回到正确的轨道上,我该如何测试方法调用已被命中?只需创建一个ExportPowerPoint对象并调用AddSlides()方法就足以触发VerifyAll()? – Novastorm
你的第一个例子将做你想做的事(如果你修复了你的界面的可见性),但正如我所说的,除了学习Moq之外,它是一个毫无价值的测试。 –
发生此异常是因为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")]
只是被帕特里克的答案殴打,将界面改为公开是要走的路 – Novastorm
看来你正在测试你的模拟。您应该使用IPowerpointExporter测试代码,并在那里验证(模拟)接口上的方法被称为 – andreasnico