gpt4 book ai didi

c# - 绑定(bind)到 Excel 应用程序事件时 MissingMethodException

转载 作者:行者123 更新时间:2023-12-03 02:48:16 24 4
gpt4 key购买 nike

我正在尝试为我创建的 Excel VSTO 加载项创建单元测试,但遇到了一个令人难以置信的神秘问题,感觉远远超出了我的经验。

在本例中,我有一个演示者:

public class Presenter
{
private readonly Excel.Application Application;

public Presenter(Excel.Application Application)
{
this.Application = Application;

Application.WorkbookActivate += Application_WorkbookActivate;
}

private void Application_WorkbookActivate(Excel.Workbook Wb)
{
// logic to be tested
}
}

我的单元测试是验证当调用 WorkbookActivate 时,它会执行特定操作,例如:

[Test]
public void TestLogicWhenWorkbookActivates()
{
var mockApplication = new Mock<Excel.Application>();

presenter = new Presenter(mockApplication.Object);

// Act
mockApplication.Raise(a => a.WorkbookActivate += null, (Excel.Workbook)null);

// Assert
// ...
}

现在,当我运行此测试时,添加事件(在演示者的构造函数中发生)时会失败,并抛出以下内容:

System.MissingMethodException:错误:类'中缺少方法'instance void [ExcelAddIns.TestControl] Microsoft.Office.Interop.Excel.AppEvents_Event::add_WorkbookActivate(class Microsoft.Office.Interop.Excel.AppEvents_WorkbookActivateEventHandler)' CaSTLe.Proxies.ApplicationProxy'。

我的理解,基于this related Stack Overflow post我正在执行的是第三方回调,并且在 Moq 4.0 之前失败。我正在使用起订量 4.2.1402.2112。

所以这是奇怪的部分:在 Stack Overflow 答案中,提到了 Moq bug 报告,它拥有一个单元测试来测试这个概念:

[Test]
public void InteropExcelTest()
{
var mockAppExcel = new Mock<Excel.Application>();

bool isDelegateCalled = false;

mockAppExcel.Object.WorkbookActivate += delegate { isDelegateCalled = true; };

mockAppExcel.Raise(ae => ae.WorkbookActivate += null, (Excel.Workbook)null);

Assert.True(isDelegateCalled);
}

这个测试确实通过了,这意味着我的第一个测试应该是有效的,因为它正确地处理了事件。但更奇怪的是,将此测试包含到我的单元测试 .cs 文件中会导致之前失败的测试 (TestLogicWhenWorkbookActivates) 通过!

这些测试是完全独立的。为什么第二个的存在会导致第一个的通过?

最佳答案

经过一些额外的研究和实验,我相信我已经解决了我的问题。我不是互操作方面的专家,所以如果我在这里做出任何错误的结论,请随时编辑或更正我。

我正在处理两个项目:

  • ExcelAddIns.TestControl
  • ExcelAddIns.TestControl.Tests

两者都需要 VSTO 引用(包括 Microsoft.Office.Interop.Excel 等)。所有 VSTO 引用都将嵌入互操作类型设置为 true(我认为这是默认设置)。根据我所读到的内容(请参阅下面的引用资料),这是问题的关键,因为它有效地分离了程序集的嵌入类型,导致当我的单元测试引用 TestControl 项目时发生冲突。

因此,我的解决方案是为两个项目中的所有 VSTO 程序集引用嵌入互操作类型设置为 false。这导致单元测试在不存在第二个测试的情况下通过。

引用文献:

Stack Overflow: Moq & Interop Types: works in VS2012, fails in VS2010?

Stack Overflow: What's the difference setting Embed Interop Types true and false in Visual Studio?

Daniel Cazzulino's Blog: Check your Embed Interop Types flag when doing Visual Studio extensibility work

关于c# - 绑定(bind)到 Excel 应用程序事件时 MissingMethodException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23089545/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com