521 Stimmen

Wie kann man abstrakte Klassen testen: mit Stubs erweitern?

Ich habe mich gefragt, wie man abstrakte Klassen und Klassen, die abstrakte Klassen erweitern, in einer Einheit testen kann.

Sollte ich die abstrakte Klasse testen, indem ich sie erweitere und die abstrakten Methoden ausblende, und dann alle konkreten Methoden testen? Dann nur die Methoden testen, die ich überschreibe, und die abstrakten Methoden in den Einheitstests für Objekte testen, die meine abstrakte Klasse erweitern?

Sollte ich einen abstrakten Testfall haben, der zum Testen der Methoden der abstrakten Klasse verwendet werden kann, und diese Klasse in meinem Testfall für Objekte erweitern, die die abstrakte Klasse erweitern?

Beachten Sie, dass meine abstrakte Klasse einige konkrete Methoden hat.

6voto

Ray Tayek Punkte 9433

Eine möglichkeit besteht darin, einen abstrakten testfall zu schreiben, der ihrer abstrakten klasse entspricht, und dann konkrete testfälle zu schreiben, die ihren abstrakten testfall unterklassieren. tun sie dies für jede konkrete unterklasse ihrer ursprünglichen abstrakten klasse (d.h. ihre testfallhierarchie spiegelt ihre klassenhierarchie wider). siehe Testen einer schnittstelle im junit-rezeptbuch: http://safari.informit.com/9781932394238/ch02lev1sec6 . https://www.manning.com/books/junit-recipes o https://www.amazon.com/JUnit-Recipes-Practical-Methods-Programmer/dp/1932394230 wenn Sie noch kein Safari-Konto haben.

siehe auch Testcase Superclass in xUnit patterns: http://xunitpatterns.com/Testcase%20Superclass.html

4voto

casademora Punkte 63718

Ich würde gegen "abstrakte" Tests argumentieren. Ich denke, ein Test ist eine konkrete Idee und hat keine Abstraktion. Wenn man gemeinsame Elemente hat, sollte man sie in Hilfsmethoden oder -klassen unterbringen, die jeder verwenden kann.

Was das Testen einer abstrakten Testklasse betrifft, so sollten Sie sich fragen, was Sie testen wollen. Es gibt verschiedene Ansätze, und Sie sollten herausfinden, was in Ihrem Szenario funktioniert. Versuchen Sie, eine neue Methode in Ihrer Unterklasse zu testen? Dann lassen Sie Ihre Tests nur mit dieser Methode interagieren. Testen Sie die Methoden in Ihrer Basisklasse? Dann haben Sie wahrscheinlich eine separate Fixture nur für diese Klasse und testen jede Methode einzeln mit so vielen Tests wie nötig.

4voto

Dies ist das Muster, dem ich normalerweise folge, wenn ich ein Harness zum Testen einer abstrakten Klasse einrichte:

public abstract class MyBase{
  /*...*/
  public abstract void VoidMethod(object param1);
  public abstract object MethodWithReturn(object param1);
  /*,,,*/
}

Und die Version, die ich zu Testzwecken verwende:

public class MyBaseHarness : MyBase{
  /*...*/
  public Action<object> VoidMethodFunction;
  public override void VoidMethod(object param1){
    VoidMethodFunction(param1);
  }
  public Func<object, object> MethodWithReturnFunction;
  public override object MethodWithReturn(object param1){
    return MethodWihtReturnFunction(param1);
  }
  /*,,,*/
}

Wenn die abstrakten Methoden zu einem Zeitpunkt aufgerufen werden, an dem ich es nicht erwarte, schlagen die Tests fehl. Wenn ich die Tests anordne, kann ich die abstrakten Methoden leicht mit Lambdas ausstatten, die Asserts ausführen, Ausnahmen auslösen, andere Werte zurückgeben usw.

3voto

Jeb Punkte 14343

Wenn die konkreten Methoden eine der abstrakten Methoden aufrufen, wird diese Strategie nicht funktionieren, und Sie sollten das Verhalten jeder Kindklasse separat testen. Andernfalls, erweitern Sie es und Stubbing die abstrakten Methoden, wie Sie beschrieben haben, sollte in Ordnung sein, wieder vorausgesetzt, die abstrakte Klasse konkrete Methoden von Kind-Klassen entkoppelt sind.

2voto

Ace Punkte 4413

Ich nehme an, Sie könnten die Basisfunktionalität einer abstrakten Klasse testen wollen... Aber Sie wären wahrscheinlich am besten dran, wenn Sie die Klasse erweitern, ohne irgendwelche Methoden zu überschreiben, und die abstrakten Methoden mit minimalem Aufwand mocken.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X