VSTOunit testing通过RequestComAddInAutomationService在C#.NET中添加Office

在过去的几周里,我一直在阅读各种StackOverflow问题和其他教程和文档(下面注意其中一些),试图找到一种unit testingVSTO AddIn的方法。

不幸的是,它总是在我的测试中导致E_NOINTERFACEexception。

我正在使用的代码如下 – 覆盖RequestComAddinAutomationService的ThisAddin部分类的一个提取,另一个描述测试实用程序接口的提取,测试本身,以及另一个程序集提取,certificateAddIn程序集及其内部对测试可见。

我的问题是 :为什么这不起作用? 我很确定这遵循VSTO测试的普遍接受的做法。

如果以下不再可能,那么应该如何测试VSTO? .NET remoting / IPC是唯一的解决方案吗?

ThisAddin.cs

 public partial class ThisAddin { #region Testing Utilities private AddinHelper _comAddinObject; protected override object RequestComAddInAutomationService() { // This is being called when I debug/run my project, but not when I run the tests return _comAddinObject ?? (_comAddinObject = new AddinHelper()); } #endregion } #region Testing Utilities [ComVisible(true)] [InterfaceType(ComInterfaceType.InterfaceIsDual)] public interface IAddinHelper { Presentation GetPresentation(); string GetString(); } [ComVisible(true)] [ClassInterface(ClassInterfaceType.None)] [ComSourceInterfaces(typeof(IAddinHelper))] public class AddinHelper : StandardOleMarshalObject, IAddinHelper { public Presentation GetPresentation() { return Globals.ThisAddin... [...]; } public string GetString() { return "Hello World!"; } } #endregion 

AssemblyInfo.cs中

 [assembly: InternalsVisibleTo("MyProject.Tests")] 

MyUnitTest.cs(引用MyProject

 [TestClass] public class BasicTest { [TestMethod] public void TestInstantiates() { var application = new Application(); var doc = application.Presentations.Open(@"C:\Presentation.pptx", MsoTriState.msoFalse, MsoTriState.msoFalse, MsoTriState.msoFalse); var comAddins = application.COMAddIns; var comAddin = comAddins.Item("MyProject"); // Returns okay var comObject = (IAddinHelper) comAddin.Object; // Exception occurs Assert.AreEqual(true, true); // Never reached doc.Close(); } } 

此外,项目的设置设置为“注册COM互操作”并且Visual Studio运行升级而没有错误 – 将其作为非管理员运行导致DLL未注册; 因此,我也知道COM对象注册。

结果exception

MyProject.Tests.dll中出现“System.InvalidCastException”类型的exception但未在用户代码中处理附加信息:无法将“System .__ ComObject”类型的COM对象强制转换为接口类型“MyProject.IAddinHelper”。 此操作失败,因为对于具有IID“{59977378-CC79-3B27-9093-82CD7A05CF74}”的接口的COM组件的QueryInterface调用由于以下错误而失败:不支持此类接口(HRESULTexception:0x80004002(E_NOINTERFACE)) 。

堆栈溢出

  • 如何从其他c#项目中调用VSTO类
  • unit testingVSTO项目
  • VSTO加载项,COMAddIns和RequestComAddInAutomationService ( Register for COM Interop不会改变任何内容)
  • 为什么我不能将我的COM对象转换为它在C#中实现的接口? (问题很可能与STAThread无关)
  • https://sqa.stackexchange.com/questions/2545/how-do-i-unit-test-word-addin-written-in-c

微软

  • https://blogs.msdn.microsoft.com/varsha/2010/08/17/writing-automated-test-cases-for-vsto-application/ < – 即使有这个据称可行的样本项目,我也能得到确切的结果。同样的错误。
  • https://msdn.microsoft.com/en-us/library/bb608621.aspx
  • 一般工作流程背景: https : //msdn.microsoft.com/en-us/library/bb386298.aspx

老实说,我不知道在没有这个工作的情况下应该如何测试VSTO加载项。

具有待测试方法的项目必须通过.Net参考选项卡使用PIA Microsoft.Office.Interop.PowerPoint。

在unit testing项目中,您必须通过COM参考选项卡使用Microsoft Powerpoint 1X.0对象库 – 它是一个ActiveX。

在此处输入图像描述

令人困惑的是在解决方案资源管理器中,它们都被称为:Microsoft.Office.Interop.Powerpoint


指定正确的引用时,您将在发生exception的行上看到此错误:

缺少编译器需要成员’Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create’

要解决此问题,只需在unit testing项目中向Microsoft.CSharp.dll添加.Net引用即可。


接下来我们将遇到您所看到的错误。

首先向Interface &class添加一个唯一的GUID(这将克服错误):

 [ComVisible(true)] [Guid("B523844E-1A41-4118-A0F0-FDFA7BCD77C9")] [InterfaceType(ComInterfaceType.InterfaceIsDual)] public interface IAddinHelper { string GetPresentation(); string GetString(); } [ComVisible(true)] [ClassInterface(ClassInterfaceType.None)] [Guid("A523844E-1A41-4118-A0F0-FDFA7BCD77C9")] [ComSourceInterfaces(typeof(IAddinHelper))] public class AddinHelper : StandardOleMarshalObject, IAddinHelper 

其次暂时使private AddinHelper _comAddinObject; 在Scope中公开(你可以在以后工作时使用[assembly:InternalsVisibleTo(“MyProject.Tests”)]

第三,检查Powerpoint是否未禁用COM加载项。 这有时会在没有Office App抱怨的情况下默默地发生。

在此处输入图像描述

最后,确保勾选注册COM。

中提琴:

在此处输入图像描述


参考:几年前我把头发拉出来帮助这个家伙: Moq和Interop类型:在VS2012中工作,在VS2010中失败了吗?