Warum erfordern Unit-Testing-Attribute normalerweise öffentliche Methoden?

12

Ich habe kürzlich festgestellt, dass das Hinzufügen von [TestInitialize] zu einer geschützten Methode in einer .NET-Assembly nicht berücksichtigt wurde, aber wenn ich die Methode öffentlich gemacht habe, wurde sie vom Unit-Test-Runner (in diesem Fall Resharper) aufgerufen. Ich habe dies in der Vergangenheit mehrfach bei Testmethoden bemerkt.

Technisch gesehen ist es genauso einfach, über eine private Methode nachzudenken wie über eine öffentliche Methode. Reflexion ist in der Tat eine Methode, mit der private Methoden einem Komponententest unterzogen werden.

Warum muss ich also alle meine Unit-Test-Methoden veröffentlichen?

Justin Dearing
quelle
2
Das ist eine wirklich gute Frage. Das einzige gute Argument, das ich gehört habe, ist, dass es dem Prinzip "Programm zu einer Schnittstelle, nicht zu einer Implementierung" folgt, das Teil der SOLID-Prinzipien ist.
Robert Harvey
9
Ich glaube nicht, dass er über das Testen seiner Klassen spricht, sondern über die tatsächlichen Testmethoden, die vom Test-Framework aufgerufen werden.
Tiger
1
@RobertHarvey in Java, Grund für ähnliche Einschränkung (zB in JUnit) ist , dass die Rahmen Designer wollen nicht zu verwirren mit setAccessibledem durch einige benutzerdefinierte Security blockiert werden kann
gnat
1
Sie müssen berücksichtigen, dass diese Entwurfsentscheidung für ein allgemeines Framework getroffen wurde, das für eine breite Verwendung vorgesehen ist. In solchen Fällen ist es für Designer nur sicherer, das Schlimmste anzunehmen und sich darauf vorzubereiten. Ich weiß nicht, ob es sich um ein firmeninternes Framework handelte (in dem die gewünschten Sicherheitsrichtlinien garantiert werden können) oder um ein Tool mit einem engen, speziellen Zweck (denken Sie an "Viewer für nicht zugreifbare Mitglieder") hätte andere Möglichkeiten zu prüfen
gnat
2
@GregBurghardt Dieses Verhalten ist in Nunit und wahrscheinlich in anderen Testframeworks zu finden, die Microsoft nicht geschrieben hat. Sicher in den Jahren, seit ich diese Frage gestellt habe, verstehe ich viel mehr über .NET, aber ich denke immer noch, dass es eine faire Frage ist, und es gibt einige gute Diskussionen in den Kommentaren.
Justin Dearing

Antworten:

2

Sie sollten testen, was die Klasse tut und nicht, wie sie es tut.

In Bezug auf die "Außenwelt" ist dies das, was die Klasse öffentlich zugänglich macht. Ihr Test-Framework geht von der gleichen Annahme aus.

Indem Sie etwas "weniger" als Public testen, tauchen Sie in die interne Implementierung der Klasse ein, was eine schlechte Idee ist.

Phill W.
quelle
Beachten Sie, dass es sich bei der Frage um die Testmethoden und nicht um die Methoden im zu testenden System handelt. OP argumentiert zwar, dass Sie Reflection verwenden können, um Dinge "weniger" als öffentlich zu testen, es ist jedoch ein Argument für die Fähigkeit von Testframeworks, auf private Methoden zuzugreifen. Das Testframework muss Reflection verwenden, um die Testmethoden zu finden (die durch ein Attribut gekennzeichnet sind), und muss daher Reflection verwenden, um Folgendes zu berücksichtigen: "Warum muss ich alle meine Komponententestmethoden öffentlich machen?"
Theraot
Testmethoden können auf private Methoden zugreifen. Mit Reflection ist alles möglich. Ich sehe diese Frage mehr in Bezug auf die [Unerwünschtheit], dies zu tun.
Phill W.
0

Im Allgemeinen ist es am besten, nur auf öffentliche Methoden zuzugreifen. Wenn Sie eine Klasse erstellen, erstellen Sie auch den Vertrag darüber, welche anderen Klassen auf Ihren Code zugreifen sollen. Die Antwort ist wahrscheinlich nur, weil es eine Konvention ist.

Vetle
quelle
1
Dies beantwortet die Frage nicht wirklich.
RubberDuck