Domanda

Qualcuno ha qualche suggerimento per testare un'unità un componente aggiuntivo per applicazione gestita per Office? Sto usando NUnit ma ho avuto gli stessi problemi con MSTest.

Il problema è che c'è un assembly .NET caricato nell'applicazione Office (nel mio caso Word) e ho bisogno di un riferimento a quell'istanza dell'assembly .NET. Non posso solo istanziare l'oggetto perché non avrebbe quindi un'istanza di Word per fare le cose.

Ora, posso usare Application.COMAddIns (" Nome del componente aggiuntivo "). Interfaccia oggetto per ottenere un riferimento, ma questo mi dà un oggetto COM che viene restituito tramite RequestComAddInAutomationService. La mia soluzione finora è che quell'oggetto abbia metodi proxy per ogni metodo nell'oggetto .NET reale che voglio testare (tutti impostati in compilazione condizionale in modo che scompaiano nella versione rilasciata).

L'oggetto COM (una classe VB.NET) in realtà ha un riferimento all'istanza del componente aggiuntivo reale, ma ho provato a restituirlo a NUnit e ho ricevuto un buon errore p / Invoke:

System.Runtime.Remoting.RemotingException: questo proxy remoto non ha un sink di canale, il che significa che il server non ha canali del server registrati in ascolto o che questa applicazione non ha un canale client adatto per comunicare con il server. at System.Runtime.Remoting.Proxies.RemotingProxy.InternalInvoke (IMethodCallMessage reqMcmMsg, uso booleano DispatchMessage, callType Int32) at System.Runtime.Remoting.Proxies.RemotingProxy.Invoke (IMessage reqMsg) at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke (MessageData & amp; msgData, tipo Int32)

Ho provato a rendere visibile il componente aggiuntivo COM principale e l'errore cambia:

System.InvalidOperationException: operazione non valida a causa dello stato corrente dell'oggetto. at System.RuntimeType.ForwardCallToInvokeMember (String memberName, flag BindingFlags, Target oggetto, Int32 [] aWrapperTypes, MessageData & amp; msgData)

Mentre ho una soluzione, è disordinato e inserisce un sacco di codice di prova nel progetto reale invece che nel progetto di prova, il che non è proprio il modo in cui NUnit dovrebbe funzionare.

È stato utile?

Soluzione

Ecco come l'ho risolto.

  1. Quasi tutto nel mio componente aggiuntivo viene eseguito dal metodo Click di un pulsante nell'interfaccia utente. Ho modificato tutti quei metodi Click in modo da consistere solo in una semplice chiamata senza parametri.

  2. Ho quindi creato un nuovo file (Classe parziale) chiamato EntryPoint che aveva un sacco di amici molto brevi, ognuno dei quali era di solito una o due chiamate a funzioni di lavoro parametrizzate, in modo che tutti i metodi Click appena richiamati questa vita. Quindi, per esempio, c'è una funzione che apre un documento standard e chiama un " salva come " nel nostro DMS. La funzione accetta un parametro di quale documento aprire e ci sono un paio di dozzine di documenti standard che usiamo.

Quindi ho

Private Sub btnMemo_Click(ByVal Ctrl As Microsoft.Office.Core.CommandBarButton, ByRef CancelDefault As Boolean) Handles btnMemo.Click
    DocMemo()
End Sub

in ThisAddin e quindi

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

nel mio nuovo file EntryPoints.

  1. Aggiungo un nuovo file AddInUtilities che ha

    IAddInUtilities dell'interfaccia pubblica

#Se DEBUG quindi

Sub DocMemo()

#End If

End Interface


Public Class AddInUtilities
    Implements IAddInUtilities
    Private Addin as ThisAddIn

#Se DEBUG quindi

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
  1. Vado al file ThisAddIn e aggiungo

    Utilità private come AddInUtilities

    Funzione di sostituzione protetta RequestComAddInAutomationService () Come oggetto     Se le utility non sono niente, allora         utilities = New AddInUtilities (Me)     Finisci se     Utilità di restituzione Fine funzione

E ora è possibile testare la funzione DocMemo () in EntryPoints usando NUnit, qualcosa del genere:

<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

L'unica cosa che non puoi quindi testare l'unità sono gli eventi Click effettivi, perché stai chiamando EntryPoints in un modo diverso, cioè attraverso l'interfaccia RequestComAddInAutomationService anziché attraverso i gestori di eventi.

Ma funziona!

Altri suggerimenti

Considera i vari framework di derisione NMock , RhinoMocks , ecc. per falsificare il comportamento di Office nei tuoi test.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top