Zum Inhalt

Unit-Test mit Datenbank und Mock

Ausgangslage ist mit Springboot implementiertes Backend.
Der Controller greift über den Service auf eine Repository-Klasse zu.
Die Repository-Klasse kapselt den Zugriff auf die Datenbank.

Controller bis DB

Ziel ist es, den Datenbankservice und den Controller zu testen, ohne dass die Datenbank selbst angesprochen wird. Dazu wird die Repository-Klasse gemockt.

Ziele:

  • Ich kann das Prinzip vom Mocken auf eine Situation mit einer Datenbank übertragen.
  • Ich kann erklären und aufzeichnen, wie der Zugriff auf die Datenbank bei einem Untittest gemockt wird.
  • Ich kann Unittests erstellen und den Zugriff auf die Datenbank mocken.
  • Ich kann bei einer Entity-Klasse Boilerplate-Code wie Getter, Setter und Constructoren vermeiden.
  • Ich kann erklären, was eine Constructor Injection ist und wieso und wie sie im Springboot-Framework verwendet wird.
  • Ich kann erklären, wieso Methoden in einem JPA-Repository keine Implementierung haben und wieso sie trotzdem funktionieren.
  • Ich kann erklären, was Optional<T> ist und wozu es eingesetzt wird.
  • Ich kann den Unterschied von @Mock und @InjectMocks erklären.
  • Ich kann die Aufteilung von Servie und Repository erklären und begründen.
  • Ich kann erklären, wieso ein Unittest fehlschlägt und wie man ihn korrigiert.

Ausgangslage

JPA-MyEntityExample.zip herunterladen


Ergebnissischerung

  • Machen Sie sich zu den folgenden Aufgaben Notizen.
  • Verfizieren Sie, ob Sie Anhand Ihrer Notizen die Lernziele erreichen können.

Aufgabe: Projekt vorbereiten und ausführen

  • Projekt herunterladen, entpacken und in der IDE öffnen.
  • Fragen zum Projekt klären.
    • Wieso gibt es beim Start der Applikation eine Fehlermeldung?
    • Kann die Applikation trotz dieser Fehlermeldung getestet werden?
    • Wieso können Sie die Unittests ausführen, obwohl die Applikation selber nicht startet? Erklären Sie den Grund.
      Hinweis: Der Test testFindByName_ReturnsNull_WhenNotFound schlägt fehlt.
      Dazu später mehr...

Aufgabe: Applikation untersuchen und verstehen

Arbeiten Sie zu zweit:

  • Erklären Sie Ihrem Lernpartner, wieso es in der Klasse MyEntity keinen Boiler-Platte-Code wie Getter, Setter, Constructoren hat.
  • Im MyEntityService finden Sie eine Constructor-Injection.
    Recherchieren Sie im Zusammenhang mit dem Springboot-Framework, was eine Constructor-Injection ist.
    Erklären Sie, wieos man eine Constructor-Injection einsetzt.
  • Im MyEntityService gibt es die beiden Methoden:
    findById
    findByName
    Erklären Sie, was diese Methoden machen.
  • Im vergleich zu MyEntityService gibt es im MyEntityRepository nur die Methode findByName jedoche nicht die Methode findById.
    Erklären Sie wieso. Erklären Sie, wieso die Methode findById im Repository keine Implementierung hat.
    (Nur eine Funktionsdeklaration)
  • Erklären Sie bei der Methode findById im Repository, was Optional<MyEntity> macht und wofür es eingesetzt wird.

Aufgabe: Unit-Tests untersuchen

Teilen auf:

  • eine/r nimmt den Test testFindById
  • eine/r nimmt den Test testFindById_ReturnsNull_WhenNotFound
  • Untersuchen Sie den Test, so dass Sie Ihrem Lernpartner jeden Schritt im Test erklären können.
  • Erklären Sie sich gegenseitig den Test.
  • Erklären Sie den Unterschied von @Mock und @InjectMocks?

Aufgabe: Service und Repository

Der Service macht doch eigentlich das Gleiche wie das Repository. Wieso braucht es den Service überhaupt, könnte man nicht direkt Unittests für das Repository schreiben? - Diskutieren Sie diese Idee. - Wenn man den Gedanken der Unittests auf nimmt, was spricht für den Sercice?


Aufgabe Unittest schlägt fehl

Der Test testFindByName_ReturnsNull_WhenNotFound schlägt fehlt. - Erklären Sie wieso. - Fixen Sie den Test, aber nur falls nötig.