2009-09-26 15 views
8

Ich habe diese Methode in meiner Datenzugriffsklasse und ich habe einen Komponententest, um sicherzustellen, dass es richtig funktioniert, aber mein Test testet die Ausnahme nicht, so meine Frage sollte ich einen neuen Test erstellen, um die Ausnahme zu erzwingen ausgelöst oder sollte ich nur darauf vertrauen, dass der catch-Block im Falle einer Ausnahme gut funktioniert? Ist es die Mühe wert?Sollte ich Ausnahmen erzwingen, um sie zu testen?

hier ein Beispiel:

public void UpdateProject(Project project) 
    { 
     using (var transaction = _session.BeginTransaction()) 
     { 
      try 
      { 
       _session.Update(project); 
       _session.Flush(); 
       transaction.Commit(); 
      } 
      catch (HibernateException) 
      { 
       transaction.Rollback(); 
       throw; 
      } 
     } 
    } 

Antwort

11

Idealerweise sollten Sie versuchen, jede Zeile Code zu testen, die Sie können ... dies eine Ausnahme bedeuten würde, zwingt die Exception-Handler auftreten zu testen, und stellen Sie sicher, das funktioniert einwandfrei.

In der Praxis wird es immer einige Codezeilen geben, die nicht abgedeckt sind - allerdings würde ich Ausnahmen durch Mocking erzwingen, um alle Exception-Handler zu testen, die Ihrer Meinung nach besonders kritisch sind oder die möglicherweise in der Produktion passieren.

+5

Es macht immer Spaß, ein Produktionsproblem zu debuggen, bei dem der Absturz im Catch-Block ist. – Mark

+2

Wenn es nur Logging und erneutes Auswerfen ist, würde ich nicht stören. Wahrscheinlich. Solange ich das Loggen woanders testete. Wenn es etwas Wichtiges tut, würde ich es tun. – serialhobbyist

+2

Ja - obwohl das Zurückrollen einer Transaktion (nicht immer) ein ziemlich schwergewichtiger Prozess sein kann, von dem ich glaube, dass er getestet werden sollte. In diesem Fall würde ich es wahrscheinlich testen. –

3

Sie könnten Ihre Sitzung dazu bringen, eine Ausnahme auszuprobieren, aber es ist wenig notwendig zu testen, ob ein Catch funktioniert.

Es ist nicht falsch, einen Test zu schreiben, um zu überprüfen, ob eine Transaktion zurückgesetzt wird, wenn ein Update eine Ausnahme auslöst, aber auf einem guten Niveau, denke ich, dass es zu weit geht.

Vielleicht würde ein aufwendiger Fall es rechtfertigen.

Auf eine zusätzliche Anmerkung, würden Sie keine Rollback auf irgendeine Art von Ausnahme?

1

Aus dem Namen der Ausnahme (HibernateException) würde ich denken, dass es kein Ausnahmefall ist. So kann es während des normalen Betriebs passieren. Wenn das der Fall ist, würde ich einen Test machen, der die Ausnahme verursacht, um sicherzustellen, dass es richtig gehandhabt wird.

9

Im Linux-Kernel befinden sich 80% der Fehler in den Treibern im Fehlerbehandlungscode.

Außergewöhnliche Behandlung ist die Quelle vieler Fehler, und Sie sollten alle Ausnahme Pfade testen.

Natürlich können Sie nicht jede Codezeile testen. Aber die Statistik sagt, dass Programmierer der Ausnahmebehandlung weniger Aufmerksamkeit schenken, also müssen Sie sie gründlich testen.

3

Ich hoffe, die Transaktion wird Rollback sein, wenn Displose() vor Commit() aufgerufen wird, brauchen Sie den Haken überhaupt?

In anderen Fällen, wenn Ihr Fang mehr tut als nur das Problem zu protokollieren, ich denke, es sollte Einheit getestet werden. Lassen Sie sich jedoch nicht davon abhalten, dass Sie einen Komponententest durchführen können.

1

Ich würde sicherlich jede spezifische Ausnahme testen, die gefangen und behandelt wird. Zumindest haben Sie einen Ausführungspfad durch Ihren Abwicklungscode, der Ihnen etwas Trost geben sollte, dass nichts Seltsames passieren wird, wenn Sie jemals während der Laufzeit auf eine solche Ausnahme stoßen.

Denken Sie daran, Sie müssen nur den Code testen, den Sie arbeiten möchten.

1

Ich hoffe, Sie würden transaction.Rollback() mit den Tests separat testen, die alle möglichen Situationen erschöpfen, die Sie denken können. Vorausgesetzt, dass die Tests erschöpfend sind, würde ich wahrscheinlich keine Ausnahme machen, da es nichts anderes im Handler gibt.

4

Hier sind meine Regeln für die ideale Testausfallverhalten:

  • Wenn Sie Abhängigkeiten verwenden die Ausnahmen auslösen könnte, dann sollten Sie Unit-Tests enthalten, die Ihre Mocks von ihnen machen Ausnahmen werfen.
  • Wenn unter bestimmten Bedingungen Ihr Code Ausnahme auslösen sollte, dann sollten Sie Komponententests einschließen, die solche Bedingungen einrichtet.

Die erste lassen Sie wissen, was Ihr Code wie unter externen Fehlern verhält, und führt oft zu erwägen, ob was zu tun ist. In allen Situationen ist es gut zu sehen, was tatsächlich passiert. Die zweite stellt nur sicher, dass Sie halten, was Sie versprechen, soweit die Fehler Ihren Code erkennen und als außergewöhnlich betrachten. Es ist nicht anders als andere Funktionen in Ihrem Code zu testen.

Bevor Sie die Unit-Test-Suite vollständig betrachten, sollten Sie einen Blick auf Code-Coverage des getesteten Codes haben. Für nicht-trivialen Code gibt es fast immer eine Möglichkeit, meinen Code-Zweig, den meine Unit-Tests nicht abdecken, oder schlimmer noch, ein Verhalten, das ich nicht beabsichtigt habe. Überraschenderweise ist die Lösung, diesen Code zu entfernen, anstatt weitere Tests hinzuzufügen. Nur Craft wurde zurückgelassen, als es früher flügelte.

Ich sage nicht unbedingt, dass man eine 100% ige Abdeckung erreichen sollte, aber man sollte Code-Coverage-getriebene Unit-Tests durchführen, weil es eine visuelle Möglichkeit ist, das existierende Code-Verhalten zu verstehen und aufzudecken. Wenn Sie es betrachten, können Sie neue Ideen für die Refaktorierung von Code erhalten, um Single Responsibility Principle und Separation of Concerns zu erreichen.

Verwandte Themen