Ric*_*den 6 vb.net add-in ms-office
有没有人对Office托管应用程序加载项的单元测试有任何建议?我正在使用NUnit,但我遇到了与MSTest相同的问题.
问题是在Office应用程序(在我的例子中是Word)中加载了.NET程序集,我需要对.NET程序集的该实例的引用.我不能只是实例化对象,因为它不会有一个Word实例来做事情.
现在,我可以使用Application.COMAddIns("addin的名称").对象接口来获取引用,但这会得到一个通过RequestComAddInAutomationService返回的COM对象.到目前为止,我的解决方案是,对于该对象,我想要测试真实.NET对象中的每个方法的代理方法(所有在条件编译下设置,以便它们在发布的版本中消失).
COM对象(一个VB.NET类)实际上有一个对真实加载项实例的引用,但我尝试将其返回给NUnit,我得到了一个很好的p/Invoke错误:
System.Runtime.Remoting.RemotingException:此远程处理代理没有通道接收器,这意味着服务器没有正在侦听的已注册服务器通道,或者此应用程序没有合适的客户端通道与服务器通信.在System.Runtime.Remoting.Proxies.RemotingProxy.InternalInvoke(IMethodCallMessage reqMcmMsg,布尔useDispatchMessage,的Int32 CALLTYPE)在System.Runtime.Remoting.Proxies.RemotingProxy.Invoke(即时聊天reqMsg)在System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke (MessageData&msgData,Int32类型)
我尝试使主加载项COM可见并且错误更改:
System.InvalidOperationException:由于对象的当前状态,操作无效.at System.RuntimeType.ForwardCallToInvokeMember(String memberName,BindingFlags flags,Object target,Int32 [] aWrapperTypes,MessageData&msgData)
虽然我有一个解决方法,它很混乱并且在实际项目中放置了大量测试代码而不是测试项目 - 这实际上并不是NUnit的工作方式.
我就是这样解决的。
我的加载项中的几乎所有内容都通过 UI 中按钮的 Click 方法运行。我已将所有这些 Click 方法更改为仅包含简单的无参数调用。
然后,我创建了一个名为 EntryPoint 的新文件(部分类),其中包含许多非常短的 Friend Sub,其中每个子通常都是对参数化工作函数的一到两次调用,以便所有 Click 方法都调用到该文件中。例如,有一个函数可以打开标准文档并调用“另存为”到我们的 DMS 中。该函数采用要打开哪个文档的参数,我们使用了几十个标准文档。
所以我有
Private Sub btnMemo_Click(ByVal Ctrl As Microsoft.Office.Core.CommandBarButton, ByRef CancelDefault As Boolean) Handles btnMemo.Click
DocMemo()
End Sub
Run Code Online (Sandbox Code Playgroud)
在 ThisAddin 中,然后
Friend Sub DocMemo()
OpenDocByNumber("Prec", 8862, 1)
End Sub
Run Code Online (Sandbox Code Playgroud)
在我的新 EntryPoints 文件中。
我添加了一个新的 AddInUtilities 文件,其中包含
公共接口 IAddInUtilities
#If DEBUG Then
Sub DocMemo()
Run Code Online (Sandbox Code Playgroud)
#End If
End Interface
Public Class AddInUtilities
Implements IAddInUtilities
Private Addin as ThisAddIn
Run Code Online (Sandbox Code Playgroud)
#If DEBUG Then
Public Sub DocMemo() Implements IAddInUtilities.DocMemo
Addin.DocMemo()
End Sub
Run Code Online (Sandbox Code Playgroud)
#End If
Friend Sub New(ByRef theAddin as ThisAddIn)
Addin=theAddin
End Sub
End Class
Run Code Online (Sandbox Code Playgroud)
我转到 ThisAddIn 文件并添加
私人公用事业作为 AddInUtilities
受保护的覆盖函数 RequestComAddInAutomationService() As Object 如果公用程序什么都没有,则公用程序 = New AddInUtilities(Me) End If 返回公用程序 End Function
现在可以使用 NUnit 测试 EntryPoints 中的 DocMemo() 函数,如下所示:
<TestFixture()> Public Class Numbering
Private appWord As Word.Application
Private objMacros As Object
<TestFixtureSetUp()> Public Sub LaunchWord()
appWord = New Word.Application
appWord.Visible = True
Dim AddIn As COMAddIn = Nothing
Dim AddInUtilities As IAddInUtilities
For Each tempAddin As COMAddIn In appWord.COMAddIns
If tempAddin.Description = "CobbettsMacrosVsto" Then
AddIn = tempAddin
End If
Next
AddInUtilities = AddIn.Object
objMacros = AddInUtilities.TestObject
End Sub
<Test()> Public Sub DocMemo()
objMacros.DocMemo()
End Sub
<TestFixtureTearDown()> Public Sub TearDown()
appWord.Quit(False)
End Sub
End Class
Run Code Online (Sandbox Code Playgroud)
然后您唯一无法进行单元测试的是实际的 Click 事件,因为您以不同的方式调用 EntryPoint,即通过 RequestComAddInAutomationService 接口而不是通过事件处理程序。
但它有效!
| 归档时间: |
|
| 查看次数: |
2212 次 |
| 最近记录: |