我正在努力解决与Visual Studio SDK“EnvDTE”相关的测试问题。假设我在EnvDTE 8.0.1,Moq 4.7.142,NUnit 2.6.4以及所有传递依赖项上都有一个带有NuGet依赖关系的C#解决方案(该解决方案可用作minimal example来制作很容易玩它。)
我的项目包含两个文件。 Foo.cs包含一些简单的逻辑,可以为某个DTE接口中定义的事件添加一个(无意义的)侦听器。
public class Foo
{
public static void Bar(Events e)
{
e.SolutionEvents.Opened += () => { };
}
}
FooTest.cs中定义的相应测试用例BarTest
创建DTE接口的模拟实例,并将其作为参数传递给Foo.Bar
。
[Test]
public void BarTest()
{
var events = Mock.Of<Events>();
var solutionEvents = Mock.Of<SolutionEvents>();
Mock.Get(events).SetupGet(evts => evts.SolutionEvents).Returns(solutionEvents);
Foo.Bar(events);
}
private void XXX()
{
Events e = null;
e.SolutionEvents.Opened += () => { };
}
实现和测试现在没有意义,但测试用例可以成功执行。
出于某种原因,如果我删除XXX
的方法声明,则此行为会发生变化。声明未标记为测试用例,也未在任何地方使用,但在删除后,测试运行将在侦听器添加到事件时产生MissingMethodException
:
System.MissingMethodException : Error: Missing method 'instance void [MyProject] EnvDTE._dispSolutionEvents_Event::add_Opened(class EnvDTE._dispSolutionEvents_OpenedEventHandler)' from class 'Castle.Proxies.ObjectProxy_1'.
at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.EventInfo.AddEventHandler(Object target, Delegate handler)
at System.Runtime.InteropServices.ComAwareEventInfo.AddEventHandler(Object target, Delegate handler)
at MyProject.Foo.Bar(Events e) in C:\Users\seb2\versioned\dte-mocking-minimal\MyProject\Foo.cs:line 25
at MyProject.Test.FooTest.BarTest() in C:\Users\seb2\versioned\dte-mocking-minimal\MyProject.Test\FooTest.cs:line 32
出于某种原因,XXX
的存在会影响测试运行,因为Moq似乎没有找到Opened
事件的定义。我发现这种行为非常奇怪,我真的不明白是什么导致了这个问题。这是Moq的问题吗?它与COM类型的类加载有关吗?
如果比我更聪明的人可以尝试解释这个问题,我将非常感激。提前致谢! :)