Ich habe einen Komponententest, bei dem ich eine nicht virtuelle Methode verspotten muss, die einen Bool-Typ zurückgibt
public class XmlCupboardAccess
{
public bool IsDataEntityInXmlCupboard(string dataId,
out string nameInCupboard,
out string refTypeInCupboard,
string nameTemplate = null)
{
return IsDataEntityInXmlCupboard(_theDb, dataId, out nameInCupboard, out refTypeInCupboard, nameTemplate);
}
}
Ich habe also ein Mock-Objekt der XmlCupboardAccess
Klasse und versuche, Mock für diese Methode in meinem Testfall wie unten gezeigt einzurichten
[TestMethod]
Public void Test()
{
private string temp1;
private string temp2;
private Mock<XmlCupboardAccess> _xmlCupboardAccess = new Mock<XmlCupboardAccess>();
_xmlCupboardAccess.Setup(x => x.IsDataEntityInXmlCupboard(It.IsAny<string>(), out temp1, out temp2, It.IsAny<string>())).Returns(false);
//exception is thrown by this line of code
}
Aber diese Zeile löst eine Ausnahme aus
Invalid setup on a non-virtual (overridable in VB) member:
x => x.IsDataEntityInXmlCupboard(It.IsAny<String>(), .temp1, .temp2,
It.IsAny<String>())
Irgendwelche Vorschläge, wie man diese Ausnahme umgehen kann?
c#
unit-testing
moq
Rahul Lodha
quelle
quelle
XmlCupboardAccess
?virtual
. Moq kann sich nicht über einen konkreten Typ lustig machen, den er nicht überschreiben kann.Antworten:
Moq kann nicht-virtuelle Methoden und versiegelte Klassen nicht verspotten. Während Sie einen Test mit einem Scheinobjekt ausführen, erstellt MOQ tatsächlich einen speicherinternen Proxy-Typ, der von Ihrem "XmlCupboardAccess" erbt und die Verhaltensweisen überschreibt, die Sie in der "SetUp" -Methode eingerichtet haben. Und wie Sie in C # wissen, können Sie etwas nur überschreiben, wenn es als virtuell markiert ist, was bei Java nicht der Fall ist. Java geht davon aus, dass jede nicht statische Methode standardmäßig virtuell ist.
Eine andere Sache, die Sie meines Erachtens in Betracht ziehen sollten, ist die Einführung einer Schnittstelle für Ihren "CupboardAccess" und die Verspottung der Schnittstelle. Dies würde Ihnen helfen, Ihren Code zu entkoppeln und auf längere Sicht Vorteile zu erzielen.
Schließlich gibt es Frameworks wie TypeMock und JustMock, die direkt mit der IL zusammenarbeiten und daher nicht virtuelle Methoden verspotten können. Beide sind jedoch kommerzielle Produkte.
quelle
Als Hilfe für alle, die das gleiche Problem wie ich hatten, habe ich versehentlich den Implementierungstyp anstelle der Schnittstelle falsch eingegeben, z
anstatt
quelle
Bitte sehen Sie, warum die Eigenschaft, die ich verspotten möchte, virtuell sein muss.
Möglicherweise müssen Sie eine Wrapper-Schnittstelle schreiben oder die Eigenschaft als virtuell / abstrakt markieren, da Moq eine Proxy-Klasse erstellt, mit der Aufrufe abgefangen und Ihre benutzerdefinierten Werte zurückgegeben werden, die Sie in den
.Returns(x)
Aufruf eingefügt haben.quelle
Anstatt eine konkrete Klasse zu verspotten, sollten Sie diese Klassenschnittstelle verspotten. Extrahieren Sie die Schnittstelle aus der XmlCupboardAccess-Klasse
Und statt
ändern
quelle
Dieser Fehler wird auch angezeigt, wenn Sie überprüfen, ob eine Erweiterungsmethode einer Schnittstelle aufgerufen wird.
Zum Beispiel, wenn Sie verspotten:
Sie erhalten dieselbe Ausnahme, da
.ValidateAndThrow()
es sich um eine Erweiterung derIValidator<T>
Schnittstelle handelt.public static void ValidateAndThrow<T>(this IValidator<T> validator, T instance, string ruleSet = null)...
quelle
Code:
aber siehe Ausnahme.
quelle