通过RequestComAddInAutomationService在C#.NET中的VSTO单元测试办公室插件 [英] VSTO Unit Testing Office AddIn in C# .NET via RequestComAddInAutomationService
问题描述
在过去的几周中,我已经研究并阅读了各种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
- 如何从其他c#项目中调用VSTO类
- 单元测试VSTO项目
- VSTO加载项,COMAddIns和RequestComAddInAutomationService (
Register for COM Interop
不会什么都不会改变 - https://sqa.stackexchange .com/questions/2545/how-do-i-unit-test-word-addin-write-in-c
- 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/<-即使使用了这个据说可行的示例项目,我遇到了完全相同的错误.
- https://msdn.microsoft.com/en-us/library /bb608621.aspx
- 常规工作流背景: https://msdn.microsoft.com/en -us/library/bb386298.aspx
- 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屋!