Unit Testing von .NET Add-In für Microsoft Office
Frage
Hat jemand irgendwelche Vorschläge für Unit-Tests eine Managed Anwendung Add-In für Office? Ich verwende NUnit, aber ich hatte die gleichen Probleme mit MSTest.
Das Problem ist, dass es eine .NET-Assembly in der Office-Anwendung (in meinem Fall, Word) und ich brauche einen Verweis auf diese Instanz von .NET Assembly geladen ist. Ich kann einfach nicht das Objekt instanziiert, weil es dann nicht eine Instanz von Word haben würde, Dinge zu tun zu.
Jetzt kann ich den Application.COMAddIns verwenden ( „Name des AddIn“). Schnittstelle Objekt einen Verweis zu bekommen, aber das wird mir ein COM-Objekt, das durch die RequestComAddInAutomationService zurückgegeben. Meine Lösung so weit ist, dass für die Objekt-Proxy-Methoden für jede Methode in dem realen .NET-Objekt zu haben, die ich (alle Satz unter bedingter Kompilierung, so dass sie in der freigegebenen Version verschwinden) testen möge.
Das COM-Objekt (eine VB.NET-Klasse) hat tatsächlich einen Verweis auf die Instanz des realen Add-in, aber ich habe gerade versucht, das zu NUnit Rückkehr und ich habe ein schönes p / Invoke-Fehler:
System.Runtime.Remoting.RemotingException: Dieser remoting Proxy hat keinen Kanal, den sink bedeutet entweder der Server hat keine registrierten Serverkanäle, die hören oder diese Anwendung hat keinen geeigneten Client-Kanal an den Server zu unterhalten. bei System.Runtime.Remoting.Proxies.RemotingProxy.InternalInvoke (IMethodCallMessage reqMcmMsg, Boolean useDispatchMessage, Int32 Calltype) bei System.Runtime.Remoting.Proxies.RemotingProxy.Invoke (IMessage reqMsg) bei System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke (Message & MsgData, Int32-Typ)
Ich habe versucht, die wichtigsten Add-In COM sichtbar und die Fehler Änderungen:
System.InvalidOperationException: Der Betrieb ist nicht gültig aufgrund des aktuellen Zustand des Objekts. bei System.RuntimeType.ForwardCallToInvokeMember (String member, Binding Flaggen, Objekt Ziel, Int32 [] aWrapperTypes, Message & MsgData)
Während ich eine Work-around habe, es ist chaotisch und bringt eine Menge Testcode in dem realen Projekt anstelle des Testprojektes -., Die nicht wirklich die Art und Weise ist NUnit gemeint ist, arbeiten
Lösung
Dies ist, wie ich es gelöst werden.
-
So gut wie alles, was in meiner Add-In läuft von der Click-Methode auf eine Schaltfläche in der Benutzeroberfläche. Ich habe all die Click-Methoden geändert nur einen einfachen, parameterlos Aufruf bestehen.
-
ich dann eine neue Datei (Partial-Klasse) erstellt genannt Entrypoint, die viele sehr kurzen Freund Subs hatte, von denen jeder war in der Regel ein oder zwei Anrufe parametrisierte Arbeiter Funktionen, so dass alle Click-Methoden aufgerufen nur in Diese Datei. So zum Beispiel gibt es eine Funktion, die ein Standard-Dokument öffnet, und fordert ein „Speichern unter“ in unser DMS. Die Funktion nimmt einen Parameter, welches Dokument zu öffnen, und es gibt ein paar Dutzend Standarddokumente, die wir verwenden.
So habe ich
Private Sub btnMemo_Click(ByVal Ctrl As Microsoft.Office.Core.CommandBarButton, ByRef CancelDefault As Boolean) Handles btnMemo.Click
DocMemo()
End Sub
in der ThisAddin und dann
Friend Sub DocMemo()
OpenDocByNumber("Prec", 8862, 1)
End Sub
in meiner neuen Einstiegspunkte Datei.
-
Ich fügen Sie eine neue Datei, die AddInUtilities hat
öffentliche Schnittstelle IAddInUtilities
#If DEBUG Then
Sub DocMemo()
#End If
End Interface
Public Class AddInUtilities
Implements IAddInUtilities
Private Addin as ThisAddIn
#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
-
Ich gehe in die ThisAddIn Datei und fügen Sie in
Privat Dienstprogramme Als AddInUtilities
Protected Overrides Function RequestComAddInAutomationService () As Object Wenn Dienstprogramme Ist Nothing Then Dienstprogramme = New AddInUtilities (Me) End If Rück Dienstprogramme End Function
Und es ist nun möglich, die DocMemo () Funktion in Einstiegspunkte zu testen, mit NUnit, so etwas wie folgt aus:
<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
Das einzige, was können Sie nicht dann sind Unit-Test der tatsächlichen Click-Ereignisse, da Sie in Einstiegspunkte in einer anderen Art und Weise anrufen, dh durch die RequestComAddInAutomationService Schnittstelle anstatt durch die Event-Handler.
Aber es funktioniert!
Andere Tipps
die verschiedenen spöttischen Frameworks NMock , RhinoMocks usw. zu fälschen das Verhalten von Office in Ihren Tests.