Testing
Last updated
Was this helpful?
Last updated
Was this helpful?
Spring Boot bietet sehr viel Komfort beim Anwendungstest. Man muß nur die richtige Annotation (injezierbare Services aufgeführt)
@SpringBootTest
@Autowired private TestRestTemplate restTemplate;
@WebMvcTest
@Autowired private MockMvc mvc;
@WebFluxTest
@RestClientTest
@Autowired private MockRestServiceServer server;
@DataJpaTest
@JdbcTest
@DataMongoTest
...
und schon kann man sich ganz zentrale Services per @Autowired
injecten als Mocks lassen. Deren Verhalten muß man allerdings häufig im Test über eine Fluent-API konfigurieren (denn man will ja unterschiedliche Szenarien testen).
Eine typische Testklasse für eine Webapplikation sieht so aus:
Dieser JUnit-Testrunner sollte grundsätzlich bei Spring-basierten Komponenten verwendet werden. Er stellt die Grundvoraussetzung dar - sonst darf man sich nicht wundern, wenn spring-spezifische Aspekte (z. B. der Aufbau des ApplicationContext aus xml-Dateien @ContextConfiguration(locations = { "classpath:mymodule-context.xml" })
) nicht funktionieren.
Diese Annotation wird eingesetzt, um die zu testenden Applikation zu initialisieren. Deshalb darf die SpringBoot-Main-Class nicht fehlen. Zudem werden evtl. noch ein paar Initializer für die Testumgebung aufgeführt (z. B. zur Initialisierung von Mocks).
Hier kann man auch Spring-Initialisierung über Spring-Kontexte in XML-Form anstoßen:
Handelt es sich um einen @IntegrationTest
, der auch eine @WebAppConfiguration
benötigt, dann sollte man vermutlich @WebIntegrationTest
verwenden. In einem WebIntegrationTest wird ein Applicationserver (Servlet-Container - per Default Toncat) gestartet
Die Applikationskonfiguration wird aus der application.properties
gezogen, kann aber über
für jeden Test übersteuert werden.
Freien Port suchen
Es macht Sinn, einen freien (!!!) Port für zu startenden Applicationserver zu suchen:
und diesen Port dann per
zu injezieren.
Das Testen von Rest-Schnittstellen läuft über TestRestTemplate
.
Da die Rest-Services ganz normale Java-Beans sind, läuft man Gefahr die Beans über Java-Aufrufe zu testen. Hierbei wird allerdings nicht die Funktionalität getestet, die ein RICHTIGER Applikationsclient verwendet. Beispielsweise wird das Marshalling/Unmarshalling nicht durchlaufen.
Diese Abkürzungen fangen am Anfang vielleicht gar nicht auf, doch spätestens, wenn beispielsweise auf HttpServletRequest
im Rest-Service zugegriffen werden soll ... eine solche Instanz dann aber gar nicht existiert.
Basic-Authentication:
new TestRestTemplate("username", "password")
MessageConverters:
RestTemplate: postForObject vs. postForEntity
Entity liefert nicht nur das eigentliche Result-Objekt des Webservice, sondern auch gleichzeitig Status-Code, ...
Empfehlung: verwende postForEntity
Beispiel:
Irgendweinen anderen Http-Client verwenden.