2010-05-06 14 views
6

Ich habe das "Replace Method with Method Object" Refactoring durchgeführt, das von Beck beschrieben wird.Wie teste ich Unit-Methoden in einem Methodenobjekt?

Jetzt habe ich eine Klasse mit einer "run()" -Methode und eine Reihe von Elementfunktionen, die die Berechnung in kleinere Einheiten zerlegen. Wie kann ich diese Mitgliedsfunktionen testen?

Meine erste Idee ist, dass meine Einheit Tests im Grunde Kopien der "run()" -Methode (mit verschiedenen Initialisierungen), aber mit Assertions zwischen jedem Aufruf an die Mitgliedsfunktionen, um den Status der Berechnung zu überprüfen.

(Ich verwende Python und das Unittest-Modul.)

class Train: 

    def __init__(self, options, points): 
     self._options = options 
     self._points = points 
     # other initializations 

    def run(self): 
     self._setup_mappings_dict() 
     self._setup_train_and_estimation_sets() 
     if self._options.estimate_method == 'per_class': 
      self._setup_priors() 
     self._estimate_all_mappings() 
     self._save_mappings() 

    def _estimate_all_mappings(): 
     # implementation, calls to methods in this class 

    #other method definitions 

Ich habe auf jeden Fall die Erwartungen darüber, was die die Zustände der Mitglied Attribute vor und nach der Anrufe an die die verschiedenen Methoden als Teil sein sollte die Implementierung der run() Methode. Sollte ich Aussagen über diese "privaten" Attribute machen? Ich weiß nicht, wie ich diese Methoden noch weiter zusammenführen könnte.

Die andere Möglichkeit ist, dass ich diese wirklich nicht testen sollte.

+0

Einige Code oder Pseudo-Code wäre hilfreich, um Ihre Frage zu verstehen. Von dem, was Sie geschrieben haben, klingt es so, als könnten Sie von der unittest.TestCase.setUp() -Methode profitieren. http://docs.python.org/library/unittest.html#unittest.TestCase.setUp – msw

+0

Ich habe Ihre Frage mit dem von Ihnen bereitgestellten Code bearbeitet. Können Sie überprüfen, ob die Einrückung korrekt ist, und ggf. erneut bearbeiten? –

+0

@ire_and_curses. Danke, ein bisschen bearbeitet. –

Antwort

10

Ich werde meine eigene Frage beantworten. Nach ein bisschen Lesen und Nachdenken glaube ich, dass ich diese privaten Methoden nicht testen sollte. Ich sollte nur die öffentliche Schnittstelle testen. Wenn die privaten Methoden, die die interne Verarbeitung durchführen, wichtig genug sind, um unabhängig zu testen und nicht nur Zufälle der aktuellen Implementierung sind, dann ist dies vielleicht ein Zeichen, dass sie in eine separate Klasse umgegliedert werden sollten.

+1

+1 für Selbstantwort und eine ziemlich gute dabei, wenn es nicht Einheitstests zugänglich ist, ist es vielleicht keine "Einheit". – msw

6

Ich mag Ihre Antwort, aber ich stimme nicht zu.

Die Situation, in der Sie dieses Entwurfsmuster verwenden würden, ist eine Situation, in der ein ziemlich komplexer Vorgang vor sich geht. Infolgedessen wäre es sehr wünschenswert, die einzelnen Komponenten einer solchen Operation zu verifizieren.

Sie haben dann das Problem der Abhängigkeiten auf anderen Ressourcen (die in diesem Fall möglicherweise wahr sind oder nicht).

Sie müssen in der Lage sein, eine Form von IOC zu verwenden, um eine Form von Mock zu injizieren, um die Klasse zu isolieren.

Neben den meisten spöttischen Frameworks erhalten Sie Accessoren, um an die privaten Mitglieder zu gelangen.

+0

Vielen Dank für diese alternative Ansicht. Ich war mir nicht bewusst, dass ich mich verspottete, wenn ich diese Frage stellte. –

+1

Ich habe auch meine Meinung geändert, seit einer mehr wie deine. Wenn Sie privat testen müssen, sollte es wahrscheinlich in eine andere Klasse verschoben werden. Ich denke jedoch, dass meine Idee immer noch für Dinge gilt, die intern sein sollten - nicht privat. –