gpt4 book ai didi

vb.net - Microsoft Office .NET 插件的单元测试

转载 作者:行者123 更新时间:2023-12-02 09:45:38 24 4
gpt4 key购买 nike

有人对 Office 托管应用程序加载项的单元测试有任何建议吗?我正在使用 NUnit,但我在使用 MSTest 时遇到了同样的问题。

问题是 Office 应用程序(在我的例子中为 Word)内加载了一个 .NET 程序集,并且我需要对该 .NET 程序集的该实例的引用。我不能只实例化该对象,因为这样它就没有 Word 实例来执行操作。

现在,我可以使用 Application.COMAddIns("Name of addin").Object 接口(interface)来获取引用,但这会获取通过 RequestComAddInAutomationService 返回的 COM 对象。到目前为止,我的解决方案是让该对象为我想要测试的真实 .NET 对象中的每个方法都拥有代理方法(所有这些方法都在条件编译下设置,以便它们在发布的版本中消失)。

COM 对象(VB.NET 类)实际上具有对真实加载项实例的引用,但我尝试将其返回到 NUnit,结果出现了一个不错的 p/Invoke 错误:

System.Runtime.Remoting.RemotingException:此远程处理代理没有 channel 接收器,这意味着服务器没有正在监听的注册服务器 channel ,或者此应用程序没有合适的客户端 channel 与服务器通信。在System.Runtime.Remoting.Proxies.RemotingProxy.InternalInvoke(IMethodCallMessage reqMcmMsg, bool useDispatchMessage,Int32 callType)在 System.Runtime.Remoting.Proxies.RemotingProxy.Invoke(IMessage reqMsg)在System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData&msgData,Int32类型)

我尝试使主加载项 COM 可见,但错误发生了变化:

System.InvalidOperationException:由于对象的当前状态,操作无效。在 System.RuntimeType.ForwardCallToInvokeMember(String memberName, BindingFlags flags, Object target, Int32[] aWrapperTypes, MessageData& msgData)

虽然我有一个解决方法,但它很困惑,并且将大量测试代码放入实际项目而不是测试项目中 - 这并不是 NUnit 真正的工作方式。

最佳答案

我就是这样解决的。

  1. 我的加载项中的几乎所有内容都通过 UI 中按钮的 Click 方法运行。我已将所有这些 Click 方法更改为仅包含简单的无参数调用。

  2. 然后,我创建了一个名为 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

在 ThisAddin 中,然后

Friend Sub DocMemo()
OpenDocByNumber("Prec", 8862, 1)
End Sub

在我的新 EntryPoints 文件中。

  • 我添加了一个新的 AddInUtilities 文件,其中包含

    公共(public)接口(interface)IAddInUtilities

  • #如果调试则

    Sub DocMemo()

    #End If

    End Interface


    Public Class AddInUtilities
    Implements IAddInUtilities
    Private Addin as ThisAddIn

    #如果调试则

    Public Sub DocMemo() Implements IAddInUtilities.DocMemo
    Addin.DocMemo()
    End Sub

    #End If

     Friend Sub New(ByRef theAddin as ThisAddIn)
    Addin=theAddin
    End Sub
    End Class
  • 我转到 ThisAddIn 文件并添加

    私有(private)实用程序作为 AddInUtilities

    protected 重写函数 RequestComAddInAutomationService() 作为对象 如果公用事业什么都不是那么 实用程序 = 新的 AddInUtilities(Me) 万一 返回公用事业结束函数

  • 现在可以使用 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

    您唯一无法进行单元测试的是实际的 Click 事件,因为您以不同的方式调用 EntryPoint,即通过 RequestComAddInAutomationService 接口(interface)而不是通过事件处理程序。

    但是它有效!

    关于vb.net - Microsoft Office .NET 插件的单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/126526/

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