Unit-test-protected-Methode in C# mit Moq
Es kam, um meine Aufmerksamkeit in letzter Zeit, dass Sie können unit-test-abstrakte Basis-Klassen mit Moq anstatt eine dummy-Klasse im test, die die abstrakte Basis-Klasse. Sehen Wie zu verwenden moq testen eine konkrete Methode in eine abstrakte Klasse? E. g. Sie tun kann:
public abstract class MyAbstractClass
{
public virtual void MyMethod()
{
//...
}
}
[Test]
public void MyMethodTest()
{
//Arrange
Mock<MyAbstractClass> mock = new Mock<MyAbstractClass>() { CallBase = true };
//Act
mock.Object.MyMethod();
//Assert
//...
}
Nun ich Frage mich, ob es eine ähnliche Technik, mir zu erlauben, test protected-Elemente ohne das erstellen einer wrapper-Klasse. I. e. wie testen Sie diese Methode:
public class MyClassWithProtectedMethod
{
protected void MyProtectedMethod()
{
}
}
Ich bin mir dessen bewusst, das Moq.Geschützt namespace, aber soweit ich es sehen kann, können Sie nur die setup-Erwartungen mit z.B.
mock.Protected().Setup("MyProtectedMethod").Verifiable();
Ich bin mir auch bewusst, dass die offensichtliche Antwort ist hier "don' T test protected-Methoden, nur zum testen public-Methoden", aber das ist eine andere Debatte! Ich will nur wissen ob dies möglich ist, mit Moq.
Update: unten ist, wie würde ich dies testen, in der Regel:
public class MyClassWithProtectedMethodTester : MyClassWithProtectedMethod
{
public void MyProtectedMethod()
{
base.MyProtectedMethod();
}
}
Vielen Dank im Voraus.
Bin wirklich Fragen, warum es keine
.Returns(..)
für die .Setup(...)
- link zur API-doc scheint kaputt zu sein und ich habe keine VS um jetzt - Sie sicher, dass keine Rückkehr? - bzlms post scheint darauf hinzudeuten, dass es ist/war einer...Nein, das ist das gleiche wie das, was ich oben geschrieben habe, es können Sie erwarten, dass die protected-Methode aufgerufen wird. Ich möchte eigentlich führen die geschützte Methode von test. I. e. Ich möchte das ändern der Zugänglichkeit der geschützten Methode, um öffentlichkeit für Testzwecke, was ich tun kann, mit einer wrapper-Klasse.
InformationsquelleAutor magritte | 2011-10-10
Du musst angemeldet sein, um einen Kommentar abzugeben.
Für den Anfang, es gibt keinen Punkt in unit-Tests eine abstrakte Methode. Es gibt keine Implementierung! Möchten Sie vielleicht unit-Tests eine unreine abstrakte Klasse, die überprüfung, dass die abstrakte Methode aufgerufen wurde:
Beachten Sie, dass ich CallBase, diesen in eine teilweise mock in den Fall, war virtuelle. Ansonsten Moq würde ersetzt haben, die Umsetzung der Do-Methode.
Protected() Sie überprüfen konnte, dass eine protected-Methode aufgerufen wurde, in einer ähnlichen Weise.
Wenn Sie erstellen ein mock mit Moq oder einer anderen Bibliothek, der springende Punkt ist, überschreiben die Umsetzung. Prüfung einer geschützten Methode umfasst das Verfügbarmachen von vorhandenen Implementierung. Das ist nicht das, was Moq ist entworfen, um zu tun. Geschützten() gibt Ihnen Zugriff (vermutlich durch reflektion, denn es ist string-basiert) zu überschreiben geschützt Mitglieder.
Entweder einen test schreiben Nachkomme Klasse mit einer Methode, ruft die protected-Methode, oder verwenden Sie die Reflexion in den unit-test aufrufen, um die protected-Methode.
Oder, besser noch, testen nicht geschützte Methoden direkt.
Der test descendant-class-Ansatz ist der, den ich habe Sie schon sehr, ich war nur daran interessiert zu wissen, ob Moq hatte eine Art, dies zu tun für mich. Die Idee kam aus dieser Frage: stackoverflow.com/questions/7691796/...
Nicht, dass ich bewusst bin. Sie schreiben, könnte eine Reflexion Helfer, die Ihnen erlauben würde, um Zugriff auf die protected-Methode; das wäre sehr kurz.
Ich nehme dies als Antwort, denn es ist mehr ein Moq bestimmte Antwort, und die Antwort ist, dass Sie nicht können. Dank beiden.
Wenn Sie die Implementierung einer Bibliothek, sagen, eine base-Klasse bereitgestellte Funktionalität soll nicht öffentlich sein, aber auf jeden Fall vorgesehen werden, die von den abgeleiteten Klassen, Sie sollten in der Lage sein, um es zu testen. Und, BTW, geschützt ist, öffentlich für die Vererbung, Hierarchie, und, zum Beispiel, das erstellen von xml-docs generiert eine Warnung für nicht kommentiert geschützten Mitglieder.
InformationsquelleAutor TrueWill
Haben Sie bereits angeschnitten, die "Prüfung der öffentlichen API, nicht privat", dachte Prozess, und du hast auch schon erwähnt, die Technik der Erben von der Klasse und dann testen Sie Ihre protected-Elemente, die Art und Weise. Beide sind gültige Ansätze.
Darunter alle, die einfache Wahrheit ist, dass Sie überlegen, dieses detail (wie das ist, was eine private oder geschützte member ist) wichtig genug ist, um zu testen, direkt, anstatt indirekt über die öffentliche API, die es verwenden würde. Wenn es ist diesem wichtigen, vielleicht ist es wichtig, ausreichend zu fördern, um seine eigenen Klasse. (Nach allem, wenn es so wichtig ist, vielleicht ist es eine Verantwortung, die
MyAbstractClass
nicht haben sollte.) Die Instanz der Klasse wäre geschützt im innerenMyAbstractClass
, so dass nur die Basis-und abgeleitete Typen müsste man Zugriff auf die Instanz, sondern der Klasse selbst würde vollständig testbar ist und sonst nutzbaren anderswo, wenn sich die wurde eine Notwendigkeit.Sonst, Sie sind Links,* die Ansätze haben Sie bereits identifiziert.
*Moq möglicherweise oder möglicherweise nicht einige Mechanismus für den Zugriff auf private oder geschützte member sind, kann ich nicht sagen, da ich nicht mit diesem bestimmten tool. Meine Antwort ist mehr von einem architektonischen Standpunkt aus.
InformationsquelleAutor Anthony Pegram
Anderen Weg in Moq anrufen geschützt ist Mitglied der folgenden Vorlage:
In Ihrer Klasse, mit geschützten member-mark Ihre Funktion als virtuelle.
Zum Beispiel:
Dann in Ihre unit-test-Verweis hinzufügen, um
und in der unit-test können Sie die folgenden schreiben:
Beachten ItExpr. Es sollte stattdessen verwendet werden. Ein weiterer gotcha erwartet Sie im Nachprüfbar. Ich weiß nicht, warum, aber ohne Berufung auf Nachprüfbare Überprüfen, werden nicht genannt.
Sorry für die Tippfehler. Sie sind richtig, es sollte CallingFunction statt. Ich korrigiere meine Antwort
InformationsquelleAutor Yuriy Zaletskyy