模拟COM Interop接口时MissingMethodException,InvalidOperationException

时间:2018-12-20 22:06:53

标签: c# unit-testing moq com-interop

我正在尝试对一个类进行单元测试,该类从COM互操作库获取接口的依赖项。

被测方法:

public void ConfigureAuth(IRequestProcessor5 processor)
{
    processor.AuthPreferences.PutIsReadOnly(false);
    // more configuration statements...
}

我真的想在这里使用递归模拟,因为我无法控制COM代码的形状。我的第一次尝试:

[Fact]
public void ConfigureAuth_SetsReadOnlyToFalse()
{
    var mockProcessor = new Mock<IRequestProcessor5>{DefaultValue = DefaultValue.Mock};
    _testSubject.ConfigureAuth(mockProcessor.Object);
    mockProcessor.Verify(p => p.AuthPreferences.PutIsReadOnly(false));
}

这将引发以下异常(来自测试中的“验证”调用):

  

System.InvalidOperationException   范围“”引用了类型为“ QBXMLRP2Lib.RequestProcessor3”的变量“ p”,但未定义。

我最初的假设是递归模拟正在运行,但是Verify表达式中发生了一些奇怪的事情,因此我尝试注释掉Verify以测试该假设。然后抛出以下异常(来自被测方法):

  

System.MissingMethodException   错误:类'Castle.Proxies.IRequestProcessor5Proxy'中缺少方法'实例类QBXMLRP2Lib.IAuthPreferences [MyProject] QBXMLRP2Lib.IRequestProcessor5 :: get_AuthPreferences()'。

因此递归嘲笑似乎有效。同样,即使在Loose模式下进行模拟,除非提供了MissingMethodException,否则Setup()也会被抛出。

这是怎么回事,我该如何解决?

1 个答案:

答案 0 :(得分:1)

要解决此问题,请在解决方案资源管理器中从单元测试项目中选择COM互操作引用。在“属性”中,将Embed Interop Types更改为False。 Moq现在将表现出与COM接口相同的效果。

我实际上不完全了解发生了什么。在Deep Magic(COM Interop)和Deep Magic(Moq的Expressions-and-DynamicProxies核心)的交集处,怪异的行为是正常的。但是,我已经确认该修复程序可以正常工作。