MOQ - Wie verspottet man eine Schnittstelle, die in eine andere Schnittstelle umgewandelt werden muss?

75

Was ich tun möchte, ist ein Moq für I1 zu erstellen - was in Ordnung ist ... aber im Verlauf der Methode, die ich teste und die dieses Modell verwendet, muss ich es in I2 umwandeln, um auf einige Eigenschaften zuzugreifen, die nicht aktiviert sind I1

Interface I1 
{ int AProperty{get;set;}}

Interface I2
{int AnotherProperty{get;set;}}

Ich habe dann einige Gegenstände

Class O1 : I1 {}

und

Class O2 : O1 , I2 {}

Das Problem ist, dass ich eine Instanz eines I2-Implementierungsobjekts in I1 umwandeln kann, um auf die Methoden zuzugreifen, die über diese Schnittstelle implementiert werden. Im Code ist dies kein Problem und alles funktioniert wie erwartet.

Das einzige Problem tritt auf, wenn ein Komponententest für diese Klasse geschrieben wird.

Die Schnittstellen stellen auch eine Methode namens GetNewInstance bereit, die eine initialisierte Instanz des implementierenden Objekts zurückgibt, das in die IGetNewInstance-Schnittstelle umgewandelt wurde. Normalerweise kann ich diese Geldstrafe verspotten und sie selbst zurückgeben lassen (und arbeite daher weiter mit dem Scheinobjekt).

Wenn Sie jedoch versuchen, dieses zurückgegebene Objekt vom Typ I2 in I1 umzuwandeln, ergibt sich eine Nullreferenz. Dies ist sinnvoll, da das Scheinobjekt, das I2 implementiert, nichts von etwas erbt, das I1 erbt.

Die Frage ist, wie ich das Scheinobjekt zwingen kann, gleichzeitig von beiden I1 und I2 zu erben.

John Nicholas
quelle

Antworten:

126

So wie ich Sie verstehe, möchten Sie ein Modell erstellen, das zwei Schnittstellen implementiert. Mit Moq ist das so einfach:

var mock = new Mock<IFoo>(); // Creates a mock from IFoo
mock.As<IBar>(); // Adds IBar to the mock
mock.As<IBar>().Setup(m => m.BarMethod()).Returns(new object()); // For setups.

Jetzt können Sie die Erwartungen einrichten und Ihre Mock verwenden , wie Sie normalerweise das Objekt verwenden würde die Umsetzung sowohl IFoound IBar.

Für Ihre GetNewInstanceMethode können Sie einfach eine Erwartung einrichten, die den Mock selbst zurückgibt.

Håvard S.
quelle
33
Übrigens, für jeden, der liest, wenn Sie die Einstellungen vornehmen, müssen Sie das mock.AS <IBAR> .Setup (......)
John Nicholas
3
Super, das funktioniert super. Wenn Sie das .Setup ausführen müssen, können Sie alles in einer Zeile ausführen. Sie müssen das As <> nicht zuerst alleine ausführen, sondern können alles in einer Zeile ausführen.
Gakera
Gibt es eine Möglichkeit, dieses Setup als Nicht-Schnittstelle durchzuführen?
Subjektive Realität