Moq & Interop Types: Funktioniert VS2012, schlägt VS2010 fehl?

Ich habe ein .NET-Bibliotheksprojekt mit ca. 500 Unit-Tests. Alle diese Tests werden in Visual Studio 2012 problemlos ausgeführt. Einige meiner Tests schlagen jedoch in Visual Studio 2010 fehl. In diesen fehlgeschlagenen Tests verwende ichMoq um mehrere Interop Types aus zu verspottenMicrosoft.Office.Interop.Excel. Der Test schlägt sofort fehl, wenn versucht wird, auf diese gespielten Interoptypen zuzugreifen:

Error: Missing method 'instance class Microsoft.Office.Interop.Excel.Range [ExcelAddIn.Core] Microsoft.Office.Interop.Excel.ListRow::get_Range()' from class 'Castle.Proxies.ListRowProxy'.

Diese Ausnahme impliziert, dass ich vergessen habe, den entsprechenden Property Getter auf meinem Mock einzurichten. Welches ist nicht der Fall:

_listRowMock.Setup(m => m.Range).Returns(_rangeMock.Object);

Jetzt kann ich mir vorstellen, dass Moq mit Interop Types nicht allzu gut funktioniert. Am verwunderlichsten finde ich jedoch, dass diese Tests in Visual Studio 2012 problemlos ausgeführt werden können, in Visual Studio 2010 jedoch fehlschlagen.

Warum beeinflusst mein Visual Studio das Verhalten meines Codes?

UPDATE: 3-11-2012

Ok, also habe ich es auf folgendes gebracht:

Ich habe zwei Projekte; Core und Core.UnitTest. Core ist die eigentliche Bibliothek, während Core.UnitTest ein Unit-Test-Projekt der Core-Bibliothek ist.Beide Projekte verweisen auf Microsoft.Office.Interop.Excel, wobei Interop-Typen einbetten aktiviert ist.Da EIT aktiviert ist, enthalten beide Projekte eine eigene "Ansicht" der Microsoft.Office.Interop.Excel-Bibliothek. Die Ansicht enthält alle Klassen, Methoden und Eigenschaften, die in ihrem jeweiligen Projekt verwendet werden.Da beide Projekte unterschiedliche Klassen, Methoden und Eigenschaften von Microsoft.Office.Interop.Excel verwenden, unterscheiden sich die eingebetteten Typen beider Bibliotheken. Z.B. ListRow in Core verfügt über eine Index- und Range-Eigenschaft, während ListRow in Core.UnitTest nur über die Range-Eigenschaft verfügt.Obwohl beide Typen unterschiedlich sind und keine gemeinsame Schnittstelle oder Superklasse haben, sind sie esÄquivalent. Dies bedeutet, dass die CLR sie so behandelt, als ob sie gleich wären, und dass Sie diese Typen über Baugruppengrenzen hinweg verwenden können. Z.B. Eine Instanz von ListRow aus Core.UnitTest funktioniert einwandfrei, wenn sie an eine Methode in der Core-Bibliothek übergeben wird. Die gemeinsam genutzte Range-Eigenschaft funktioniert, während die fehlende Index-Eigenschaft beim Zugriff eine MissingMethodException auslöst.Das oben erwähnte Verhalten funktioniert sogar mit verspotteten Typen. Ein verspottetes Objekt von Mock [Excel.ListRow] funktioniert einwandfrei, wenn die Baugruppengrenze überschritten wird.Leider funktioniert das im vorherigen Punkt beschriebene Verhalten nur, wenn ich meine Assemblys in Visual Studio erstelle2012. Wenn ich meine Assemblys in Visual Studio erstelle2010 Wenn ich meinen Code debugge, kann ich sehen, dass die verspottete ListRow-Instanz an eine Methode meines Core-Projekts übergeben wird. Sobald die Instanz die Baugruppengrenze überschreitet, verlieren alle Methoden und Eigenschaften von ListRow ihre Implementierung und lösen MissingMethodExceptions aus.Nun zum spaßigen Teil, ich habe es tatsächlich geschafft, dieses Problem zu mindern, indem sichergestellt wurde, dass beide eingebetteten ListRow-Typen ausgerichtet sind. Z.B. Damit der Compiler in beiden Projekten dieselbe Ansicht von ListRow erstellt, habe ich sichergestellt, dass ich in meinem UnitTest-Projekt genau dieselben Methoden und Eigenschaften verwendet habe. Dies bedeutet das Hinzufügen von Dummy-Zeilen wie: var dummy = listRow.Index. Nachdem der Compiler identische Ansichten meines eingebetteten ListRow-Typs erstellt hatte, durfte die Instanz Baugruppengrenzen überschreiten, ohne ihre Implementierung zu verlieren.

Die Frage bleibt jedoch weiterhin: Was verursacht diesen Unterschied im Verhalten zwischen Visual Studio 2010 und Visual Studio 2012?

UPDATE: 9-11-2012

Demo-Lösung: http://temp-share.com/show/KdPf6066h

Ich habe eine kleine Lösung erstellt, um den Effekt zu demonstrieren. Die Lösung besteht aus einer Bibliothek und einem UnitTest-Projekt. Beide verweisen auf Microsoft.Office.Interop.Excel.Range mit aktiviertem EIT. Der Test funktioniert in VS2012 einwandfrei, löst jedoch in VS2010 eine MissingMethodException aus. Wenn Sie die Dummy-Zeile im Test aus dem Kommentar entfernen, funktioniert sie in VS2010.

LETZTE ÄNDERUNG: 29-12-2012

Ich entschuldige mich für das späte Update. Ein Kollege von mir hat eine Lösung gefunden, die ich jedoch auf meinem Computer nicht reproduzieren konnte. In der Zwischenzeit hat unser Unternehmen auf TFS2012 umgestellt, sodass dies für mich kein Problem mehr darstellt. Die beiden wichtigsten Schlussfolgerungen meines Kollegen waren:

Die Semantik der "Any CPU" -Plattform wurde von Visual Studio 2010 in Visual Studio 2012 geändert. Dies führt dazu, dass unterschiedliche DLLs generiert werden, je nachdem, ob Sie VS2010 oder VS2012 verwenden.Beide Projekte verwiesen auf unterschiedliche Versionen von Microsoft.Office.Interop.Excel.

Ich habe meine Projekte überprüft und die Referenzen korrigiert, aber es machte keinen Unterschied. Danach habe ich sowohl in VS2010 als auch in VS2012 verschiedene Plattformvarianten ausprobiert, konnte jedoch kein zufriedenstellendes Ergebnis erzielen. Ich werde Jeremys Antwort akzeptieren, da sie am hilfreichsten war. Vielen Dank für Ihre Hilfe.

Antworten auf die Frage(4)

Ihre Antwort auf die Frage