2 Stimmen

Was ist die Strategie für Unit-Tests bei der Weiterleitung von Methodenaufrufen?

Ich habe das folgende Szenario:

public class CarManager
{
  ..

  public long AddCar(Car car)
  {
      try
      {
         string username = \_authorizationManager.GetUsername();
         ...
         long id = \_carAccessor.AddCar(username, car.Id, car.Name, ....);
         if(id == 0)
         {
             throw new Exception("Car was not added");
         }
         return id;
      } catch (Exception ex) {
         throw new AddCarException(ex);
      }
  }

  public List AddCars(List cars)
  {
     List ids = new List();
     foreach(Car car in cars)
     {
         ids.Add(AddCar(car));
     }
     return ids;
  }
}

Ich bin mocking aus _reportAccessor, _authorizationManager etc.

Jetzt möchte ich die Klasse CarManager ungetestet haben. Sollte ich mehrere Tests für AddCar() haben, wie zum Beispiel

AddCarTest()
AddCarTestAuthorizationManagerException()
AddCarTestCarAccessorNoId()
AddCarTestCarAccessorException()

Sollte ich für AddCars() alle vorherigen Tests wiederholen, da AddCars() AddCar() aufruft - es scheint, als würde man sich wiederholen? Sollte ich vielleicht nicht AddCar() von AddCars() aufrufen? < p/>

Bitte um Hilfe.

0 Stimmen

Der Code wird nicht vollständig angezeigt, wenn man versucht, ihn zu reparieren.

2voto

Garth Gilmour Punkte 10840

Hier gibt es zwei Probleme:

  • Unit-Tests sollten mehr tun als nur einzelne Methoden zu testen. Sie sollten so konzipiert sein, dass sie beweisen, dass Ihre Klasse die Aufgabe erfüllen kann, für die sie entwickelt wurde, wenn sie in das übrige System integriert wird. Sie sollten also die Abhängigkeiten simulieren und dann einen Test für jede Art und Weise schreiben, in der Ihre Klasse tatsächlich verwendet wird. Für jede (nicht-triviale) Klasse, die Sie schreiben, wird es Szenarien geben, in denen der Client-Code Methoden nach einem bestimmten Muster aufruft.
  • Es ist in Ordnung, wenn AddCars AddCar aufruft. Sie sollten Tests zur Fehlerbehandlung wiederholen, aber nur, wenn es einem Zweck dient. Eine der inoffiziellen Regeln für Unit-Tests lautet: "Testen bis zur Langeweile" oder (wie ich es gerne sehe) "Testen, bis die Angst verschwindet". Sonst würden Sie ewig Tests schreiben. Wenn Sie also davon überzeugt sind, dass ein Test keinen zusätzlichen Nutzen bringt, schreiben Sie ihn nicht. Es kann natürlich sein, dass Sie sich irren. In diesem Fall können Sie später darauf zurückkommen und ihn einbauen. Sie müssen nicht gleich beim ersten Mal einen perfekten Test erstellen, sondern nur eine solide Grundlage, auf der Sie aufbauen können, wenn Sie besser verstehen, was Ihre Klasse tun muss.

0 Stimmen

+1 für einen pragmatischen Ansatz bei der Prüfung. Außerdem wäre es eine schreckliche Verletzung des DRY-Prinzips, wenn AddCar nicht von AddCars aufgerufen würde.

1voto

Andreas Bakurov Punkte 1475

Der Unit Test sollte sich nur auf die entsprechende zu testende Klasse konzentrieren. Alle Attribute der Klasse, die nicht vom gleichen Typ sind, sollten gespottet werden.

Angenommen, Sie haben eine Klasse (CarRegistry), die eine Art von Datenzugriffsobjekt (z.B. CarPlatesDAO) verwendet, das Autokennzeichen aus einer relationalen Datenbank lädt/speichert.

Wenn Sie die CarRegistry testen, sollten Sie sich nicht darum kümmern, ob CarPlateDAO korrekt funktioniert; denn unser DAO hat einen eigenen Unit-Test.

Sie erstellen einfach einen Mock, der sich wie ein DAO verhält und entsprechend dem erwarteten Verhalten richtige oder falsche Werte zurückgibt. Sie schließen diese Mock-DAO an Ihre CarRegistry an und testen nur die Zielklasse, ohne sich darum zu kümmern, ob alle aggregierten Klassen "grün" sind.

Mocking ermöglicht die Trennung von testbaren Klassen und eine bessere Konzentration auf bestimmte Funktionen.

1voto

MvdD Punkte 19735

Erstellen Sie beim Unittest der Klasse AddCar Tests, die jeden Codepfad testen. Wenn _authorizationManager.GetUsername() eine Ausnahme auslösen kann, erstellen Sie einen Test, bei dem Ihr Mock für dieses Objekt ausgelöst wird. Übrigens: Werfen oder fangen Sie keine Instanzen von Exception, sondern leiten Sie eine sinnvolle Exception-Klasse ab.

Für die Methode AddCars sollten Sie auf jeden Fall AddCar aufrufen. Aber Sie könnten erwägen, AddCar virtuell zu machen und es zu überschreiben, nur um zu testen, dass es mit allen Autos in der Liste aufgerufen wird.

Manchmal muss man das Design der Klasse ändern, um sie testen zu können.

1voto

Josh Freed Punkte 61

Es ist eine gute Praxis, Tests zu schreiben, die alle möglichen Szenarien innerhalb einer Methode untersuchen. Auf diese Weise führe ich in meinen Projekten Unit-Tests durch. Tests wie AddCarTestAuthorizationManagerException() , AddCarTestCarAccessorNoId() ou AddCarTestCarAccessorException() Sie bringen einen dazu, über die verschiedenen Möglichkeiten nachzudenken, wie der eigene Code scheitern kann, was dazu geführt hat, dass ich neue Arten von Fehlern für eine Methode gefunden habe, die ich sonst vielleicht übersehen hätte, und dass ich den Gesamtentwurf der Klasse verbessert habe.

In einer Situation wie AddCars() aufrufen AddCar() Ich würde mich über die AddCar() Methode und zählen Sie, wie oft sie aufgerufen wird von AddCars() . Die Mocking-Bibliothek, die ich verwende, ermöglicht es mir, ein Mock von CarManager zu erstellen und nur die AddCar() Methode, aber nicht AddCars() . Dann kann Ihr Unit-Test festlegen, wie oft er erwartet AddCar() aufzurufen, was man an der Größe der Liste der übergebenen Fahrzeuge erkennen kann.

0 Stimmen

Würden Sie für die Mocked-Methode AddCar zurückgeben alle verschiedenen Arten von Ausnahmen von es zu testen, die in AddCars sowie oder betrachten Sie, dass redundant, wie es in AddCar Tests getestet wird?

1voto

Paul Smith Punkte 1034

Sollte ich mehrere Tests für AddCar() haben, wie zum Beispiel

AddCarTest() AddCarTestAuthorizationManagerException() AddCarTestCarAccessorNoId() AddCarTestCarAccessorException()

Unbedingt! Das verrät Ihnen wertvolle Informationen

Sollte ich für AddCars() alle vorherigen Tests wiederholen, da AddCars() AddCar() aufruft - es scheint als würde man sich wiederholen? Sollte ich vielleicht nicht AddCar() von AddCars() aufrufen?

Der Aufruf von AddCar aus AddCars ist eine großartige Idee, da er die Verletzung des DRY-Prinzips vermeidet. In ähnlicher Weise sollten Sie Tests wiederholen. Sehen Sie es so - Sie haben bereits Tests für AddCar geschrieben So können Sie beim Testen von AddCards davon ausgehen, dass AddCar das tut, was auf der Verpackung steht .

Stellen wir uns einmal vor, AddCar wäre in einer anderen Klasse. Sie hätten keine Kenntnis von einem Autorisierungsmanager. Test AddCars ohne das Wissen, was AddCar zu tun hat.

Für AddCars müssen Sie alle normalen Randbedingungen testen (funktioniert eine leere Liste usw.). Sie müssen wahrscheinlich nicht die Situation testen, in der AddCar eine Ausnahme auslöst, da Sie nicht versuchen, diese in AddCars abzufangen.

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