通过RequestComAddInAutomationService在C#.NET中的VSTO单元测试办公室插件 [英] VSTO Unit Testing Office AddIn in C# .NET via RequestComAddInAutomationService

查看:93
本文介绍了通过RequestComAddInAutomationService在C#.NET中的VSTO单元测试办公室插件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在过去的几周中,我已经研究并阅读了各种StackOverflow问题以及其他教程和文档(以下是其中的一些),以尝试找到一种对VSTO加载项进行单元测试的方法.

I have worked and read through various StackOverflow questions and other tutorials and documentation over the past weeks (N.B. some of them below) to try and find a way of unit testing a VSTO AddIn.

不幸的是,在我的测试中,它总是导致E_NOINTERFACE异常.

Unfortunately, it always results in an E_NOINTERFACE exception in my tests.

我正在使用的代码如下-覆盖RequestComAddinAutomationService的ThisAddin子类的一个摘录,另一个描述了测试实用程序接口,测试本身,以及另外的汇编摘录,证明了AddIn汇编及其内部结构对测试可见.

The code I am using is below - one extract of the ThisAddin partial class overriding the RequestComAddinAutomationService, another describing the test utility interface, the test itself, as well as an additional assembly extract proving that the AddIn assembly and its internals are visible to the test.

我的问题是:为什么这不起作用?我很确定这遵循VSTO测试的公认惯例.

My question is: why is this not working? I am pretty sure that this follows the generally accepted practices of VSTO testing.

如果无法再进行以下操作,应该如何测试VSTO? .NET远程处理/IPC是唯一的解决方案吗?

If the below is not possible anymore, how should one go about testing VSTO? Is .NET remoting/IPC the only solution?

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的引用)

MyUnitTest.cs (has a reference to 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对象 已注册.

Furthermore, the project's settings are set to "Register for COM interop" and Visual Studio runs elevated without errors - running it as non-admin results in the DLLs not being registered; therefore, I also know that the COM objects are registered.

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

An exception of type 'System.InvalidCastException' occurred in MyProject.Tests.dll but was not handled in user code Additional information: Unable to cast COM object of type 'System.__ComObject' to interface type 'MyProject.IAddinHelper'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{59977378-CC79-3B27-9093-82CD7A05CF74}' failed due to the following error: No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE)).

StackOverflow

StackOverflow

  • How to call VSTO class from other c# project
  • Unit Testing VSTO projects
  • VSTO Add-ins, COMAddIns and RequestComAddInAutomationService (Register for COM Interop doesn't change anything)
  • Why cannot I cast my COM object to the interface it implements in C#? (the issue is likely not STAThread related)
  • https://sqa.stackexchange.com/questions/2545/how-do-i-unit-test-word-addin-written-in-c

Microsoft

Microsoft

  • https://blogs.msdn.microsoft.com/varsha/2010/08/17/writing-automated-test-cases-for-vsto-application/ <-- Even with this supposedly working sample project, I am getting the exact same error.
  • https://msdn.microsoft.com/en-us/library/bb608621.aspx
  • General workflow background: https://msdn.microsoft.com/en-us/library/bb386298.aspx

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

I honestly don't know how one is supposed to test VSTO Add-Ins without this working.

推荐答案

解决方案

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

Solution

The Project with methods to be Tested has to use the PIA Microsoft.Office.Interop.PowerPoint via the .Net reference tab.

在单元测试项目中,您必须通过 COM参考选项卡-其ActiveX使用Microsoft Powerpoint 1X.0对象库.

In the Unit Test Project you have to use the Microsoft Powerpoint 1X.0 Object Library via the COM reference tab - its an ActiveX.

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

The confusing thing is in Solution Explorer they are both called: Microsoft.Office.Interop.Powerpoint

指定正确的引用后,您会在发生异常的行上看到此错误:

When you specify the correct References you'll see this error on the line where the exception occurs:

缺少编译器所需的成员'Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create'

Missing compiler required member 'Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create'

要解决此问题,只需在单元测试项目中为Microsoft.CSharp.dll添加.Net引用即可.

To solve that simply add a .Net reference to the Microsoft.CSharp.dll in the Unit Test project.

接下来,我们将遇到您遇到的错误.

Next we will run into the error you're seeing.

首先将唯一的GUID添加到接口&中.类(这将克服错误):

Firstly add a unique GUID to the Interface & class (this will overcome the error):

[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;在范围中公开(可以在以后工作时进行[assembly:InternalsVisibleTo("MyProject.Tests")]).

第三,检查Powerpoint尚未禁用COM加载项.有时这会默默发生,而不会抱怨Office App.

Thirdly, check that Powerpoint has not disabled the COM add-in. This sometimes happens silently, without the Office App complaining.

最后,确保选中注册COM".

Lastly, make sure Register for COM is ticked.

中提琴:

参考:几年前,我在帮助这位研究员的过程中竭尽全力:

Ref: I pulled my hair out working this out years ago helping this fellow SO'r: Moq & Interop Types: works in VS2012, fails in VS2010?

这篇关于通过RequestComAddInAutomationService在C#.NET中的VSTO单元测试办公室插件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆