|
|
Die Tests zum Testen des Rest-Verticles befinden sich im `src/test/java/de/thm/mni/swtp/feedbackapp/backend/rest` Ordner und können mit `./mvnw test` ausgeführt werden.
|
|
|
|
|
|
## Basis Klassen
|
|
|
|
|
|
Alle Test-Klassen erben von der `TestBase`-Klasse. Diese enthält Methoden zum Durchführen von Anfragen an die Rest-API und zum Starten der Vertx Anwendung und Vorbereitung der Datenbank.
|
|
|
|
|
|
### Request-Methode
|
|
|
|
|
|
Die `request` Methode ist die wichtigste Methode, die durch das Erben von `TestBase` erhalten wird. Sie erlaubt es (authentifizierte-)Anfragen an die REST-API zu senden.
|
|
|
|
|
|
```java
|
|
|
Future<HttpResponse<Buffer>> request(String path, HttpMethod method, String authorized, Object body);
|
|
|
```
|
|
|
|
|
|
Der `path` Parameter ist der API-Pfad der Route, an welche die Test-Anfrage gesendet werden soll.
|
|
|
`method` ist die HTTP Methode, die dabei verwendet werden soll.
|
|
|
`authorized` ist der Name des Users, als welcher die Anfrage gesendet werden soll (`"user"`, `"user1"`, `"user2"`, `"user3"`, `"user4"` und `null`) sind mögliche Werte. Bei `null` erfolgt keine Authentifizierung.
|
|
|
`body` kann entweder ein `JsonObject` oder ein `JsonArray` sein und wird als HTTP-Request-Body verwendet.
|
|
|
|
|
|
Die Vert.X-HTTP-Antwort ist in der [Vertx-Dokumentation](https://vertx.io/docs/apidocs/io/vertx/ext/web/client/HttpResponse.html) dokumentiert.
|
|
|
|
|
|
Die wichtigsten Methoden sind `statusCode()`, welche den HTTP-Status-Code der Antwort zurückgibt. Dieser sollte immer mithilfe eines Asserts überprüft werden. `bodyAsJsonObject()`/`bodyAsJsonArray()` geben den HTTP-Body (als `JsonObject` oder `JsonArray`) zurück. Dieser sollte auch mithilfe von Assertions auf seine Richtigkeit überprüft werden.
|
|
|
|
|
|
### SessionTestBase
|
|
|
|
|
|
`SessionTestBase` ist eine Erweiterung der `TestBase` Klasse, welche anstelle des User-Tokens den Session-Token
|
|
|
verwendet. `SessionTestBase` sollte daher immer dann verwendet werden, wenn eine Route getestet werden soll, welche einen Session-Token benötigt.
|
|
|
|
|
|
```java
|
|
|
protected static Future<HttpResponse<Buffer>> request(String path, HttpMethod method, String sessionTokenKey, Object body)
|
|
|
```
|
|
|
|
|
|
Die `request`-Methode enthält alle Parameter ihres TestBase-Äquivalents mit dem einzigen Unterschied, dass anstelle eines Benutzer*innennamens ein Session-Token übergeben wird.
|
|
|
|
|
|
## Test Beispiel
|
|
|
|
|
|
```java
|
|
|
public class GetCourseTest extends TestBase { // Erweitert TestBase
|
|
|
// ...
|
|
|
|
|
|
@Test
|
|
|
public void getExistingCourse(TestContext context) {
|
|
|
int id = CreateCourseTest.courseIDs.get("courseWithNameAndDescriptionAndSemester");
|
|
|
getCourse(context, id, "user", 200,
|
|
|
CreateCourseTest.courseWithNameAndDescriptionAndSemester.copy().put("id", id).put("protected", false));
|
|
|
}
|
|
|
|
|
|
// ...
|
|
|
|
|
|
@Test
|
|
|
public void getNonExistingCourse(TestContext context) {
|
|
|
getCourse(context, 10000000, "user", 404, null);
|
|
|
}
|
|
|
|
|
|
// ...
|
|
|
|
|
|
private void getCourse(TestContext context, int courseID, String user, int expectedStatus, JsonObject expectedBody) { // Anfrage und Überprüfung der Antwort sollte in separater Methode erfolgen und nicht im Testfall um Code-Duplikation zu vermeiden
|
|
|
Async async = context.async(); // Wichtig damit Test als Asynchroner Test behandelt wird und nicht Vorbeenden aller Asynchronen-Operationen als erfolgreich gewertet wird
|
|
|
request("/api/courses/" + courseID, HttpMethod.GET, user, null).onSuccess(res -> { // Durchführen der Anfrage
|
|
|
context.assertEquals(expectedStatus, res.statusCode()); // Sicherstellen, das der Status-Code mit Erwartungswert übereinstimmt
|
|
|
JsonObject body = res.bodyAsJsonObject(); // Erhalten des bodies
|
|
|
if (expectedBody != null) { // Wenn ein Body erwartet wird überprüfen ob dieser mit dem erwartetem übereinstimmt
|
|
|
context.assertEquals(expectedBody.getInteger("id"), body.getInteger("id"));
|
|
|
context.assertEquals(expectedBody.getString("name"), body.getString("name"));
|
|
|
context.assertEquals(expectedBody.getString("description"), body.getString("description"));
|
|
|
context.assertEquals(expectedBody.getBoolean("protected"), body.getBoolean("protected"));
|
|
|
JsonObject docent = body.getJsonObject("docent");
|
|
|
context.assertNotNull(docent); // Auch unter-Objekte von Antworten sollten überprüft werden
|
|
|
context.assertEquals(true, docent.getBoolean("docent"));
|
|
|
}
|
|
|
async.complete(); //Wenn fertig muss complete aufgerufen werden damit JUnit weiß das alle asynchronen Operationen beendet wurden
|
|
|
}).onFailure(context::fail); // Behandlung von Asynchronen Fehlern ist wichtig, da diese nicht automatisch von JUnit erkannt werden und dies dazu führt, dass der Test bei Auftretten eins Fehlers nicht weiterläuft
|
|
|
}
|
|
|
}
|
|
|
``` |