2008-09-24 48 views
5

有沒有人對單元測試託管應用程序加載項的Office有任何建議?我使用的是NUnit,但我遇到了與MSTest相同的問題。用於Microsoft Office的.NET加載項的單元測試

問題是在Office應用程序(在我的情況下,Word)中加載了.NET程序集,我需要對.NET程序集實例的引用。我不能僅實例化對象,因爲它不會有Word的實例來處理事情。

現在,我可以使用Application.COMAddIns(「外掛的名稱」)。對象接口來獲取引用,但是我得到一個通過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:操作無效由於對象的當前狀態。 在System.RuntimeType.ForwardCallToInvokeMember(字符串成員名稱,標誌的BindingFlags,對象目標的Int32 [] aWrapperTypes,MessageData & MSGDATA)

雖然我有一個變通,它的混亂,並把大量的測試代碼中的實際項目而不是測試項目 - 這實際上並不是NUnit的工作方式。

回答

2

這就是我解決這個問題的方法。

  1. 幾乎在我加載項中的所有內容都是從UI中按鈕的Click方法運行的。我已將所有這些Click方法更改爲僅包含一個簡單的無參數調用。

  2. 然後我創建了一個名爲EntryPoint的新文件(Partial Class),它有很多非常短的Friend Subs,每個文件通常都是一次或兩次調用參數化工作器函數,以便所有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 
在我的新入口點文件

  • 我添加具有

    公共接口IAddInUtilities

  • #If DEBUG Then

    Sub DocMemo() 
    

    #End If

    新AddInUtilities文件210

    #If DEBUG Then

    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文件,並在

    私人公用事業添加作爲AddInUtilities

    受保護的覆蓋樂趣ction RequestComAddInAutomationService()作爲對象 如果Utilities是沒有那麼 公用事業=新AddInUtilities(ME) 結束如果 返回公用事業 端功能

  • 而現在有可能使用測試在入口點的DocMemo()函數NUnit的,是這樣的:

    <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事件,因爲你通過RequestComAdd調入入口點以不同的方式,即唯一InAutomationService接口而不是通過事件處理程序。

    但它的工作!

    2

    考慮各種嘲諷框架NMockRhinoMocks等在您的測試中僞造Office的行爲。

    +1

    我不得不嘲笑Office的整個工作! – 2009-01-14 15:01:39