Jörn Hameister Deutschen Telekom AG

Es gibt keine Ausreden mehr, für Spring-Boot-Applikationen keine Tests zu schreiben.

Da die verschiedenen Architekturschichten einer Spring-Boot-Anwendung über APIs kommunizieren, müssen auch diese getestet werden. Wir werfen einen Blick auf Spring-eigene und externe Methoden für das Testing. Mockito, REST Assured, MockMvc, HtmlUnit, JSON Test sowie TestEntityManager helfen dabei, API-Tests einfacher und kürzer zu machen.

Zurzeit wird viel über Microservices und Self-contained Systems geredet und geschrieben. Häufig werden diese Services und Systeme mit Spring Boot implementiert. Spring-Boot-Applikationen sind oft nach einem ähnlichen Muster aufgebaut und bestehen gewöhnlich aus mehreren Schichten, die miteinander Informationen austauschen. Für jede dieser Schichten müssen prinzipiell Unit-Tests geschrieben werden und für die gesamte Applikation gegebenenfalls Integrations-, Akzeptanz- und Lasttests. Bedingt durch diese Architektur müssen verschieden APIs getestet werden: die Service-APIs, die REST-APIs und die APIs von anderen Klassen mit einer öffentlichen Schnittstelle innerhalb der Spring-Boot-Applikation. Für jede dieser Schichten gibt es Hilfsmittel, um sie zu testen und die Korrektheit sicherzustellen.

In Abbildung 1 sind die verschiedenen Komponenten einer Spring-Boot-Applikation zu sehen. Es gibt meist einen REST-Controller mit öffentlichen Schnittstellen sowie einen internen Service, der die Businesslogik enthält und über Repositories auf eine Datenbank zugreift. Für jede dieser Komponenten gibt es die passenden Testmöglichkeiten. Grafische Oberflächen klammern wir hier einmal aus. In diesem Artikel wird als Beispiel eine Applikation verwendet, die Items verwaltet, die jeweils eine id, eine Beschreibung (description), einen Standort (location) und ein Datum (itemdate) besitzen. Das ItemRepository ist in Listing 1 zu sehen. Zu beachten ist, dass in dem Beispiel die Methode findByLocation nur dazu dient, um später zu zeigen, wie der TestEntityManager verwendet werden kann.

Abb. 1: Häufiger Aufbau einer Spring-Boot-Applikation mit möglichen Hilfsmitteln zum Testen der Schichten

Abb. 1: Häufiger Aufbau einer Spring-Boot-Applikation mit möglichen Hilfsmitteln zum Testen der Schichten

Test als Living Documentation

Man sollte sich beim Schreiben von Tests immer vergegenwärtigen, dass man mit einem Test auch das Verhalten einer Funktionalität zu einem bestimmten Zeitpunkt überprüft. Das heißt, der Test dient nicht nur dazu, eine Funktion zu testen, sondern auch dazu, Verhaltensänderungen festzustellen. Ändert sich beispielsweise das Verhalten einer Methode, sollte ein fehlschlagender Test darauf aufmerksam machen. Auf den ersten Blick wirken deshalb Unit-Tests oft sinnlos, weil offensichtlich ist, dass der zu testende Code richtig ist und macht, was man erwarten würde. Aber in Zukunft könnten sich kleine Dinge am Code oder den Eingangsparametern ändern, sodass sich das Verhalten in einem Ausmaß ändert, das man nicht erwartet hat. Außerdem dient ein Test damit auch indirekt der Dokumentation. Im Kontext von Behavior-driven Development (BDD) bezeichnet man das als Living Documentation. Durch Wahl eines sinnvollen Testnamens dokumentiert man gleichzeitig den Programmcode und erleichtert die zukünftige Pflege und Weiterentwicklung. Es ist ja allgemein bekannt, dass das JavaDoc zwar initial geschrieben wird, um das Quality Gate bei Sonar zu schaffen, aber später weder gelesen noch gepflegt wird. Deshalb sind sprechende Methodennamen für Tests der bessere Weg.

 
@org.springframework.stereotype.Repository
public interface ItemRepository extends Repository<Item, Long> {
  Item findOne(Long id);
  List findAll();
  List findByLocation(String location);
  Item save(Item item);
  void delete(Long id);
}

In dem Interface ItemRepository wird einfach das Interface org.springframework.data.repository.Repository um die Methoden erweitert, die in der Anwendung benötigt werden. Es wurde also bewusst das Interface Repository verwendet und nicht JpaRepository oder CrudRepository. Der Grund dafür ist, dass nur das exponiert werden sollte, das notwendig ist.

Den vollständigen Artikel lesen Sie in der Ausgabe:

Java Magazin 8.17 - "Agile und DevOps"

Alle Infos zum Heft
579804071Hausmittel zum Testen von APIs in Spring-Boot-Applikationen
X
- Gib Deinen Standort ein -
- or -