Spring Boot: Integrationstests der REST-API in Spring Boot

In diesem Tutorial wird erläutert, wie Sie die REST-API für Integrationstests in Spring Boot schreiben. Dieses Tutorial verwendet die im vorherigen Tutorial geschriebenen Beispiele. In diesem Tutorial sollen automatisierte Tests mit JUnit erstellt und mit der Spring Boot-Anwendung ausgeführt werden.

In diesem Tutorial wird davon ausgegangen, dass der Leser bereits über ausreichende Kenntnisse über die Spring REST-Webdienste verfügt. Wenn Sie grundlegende Details zu Spring We Services erfahren möchten, lesen Sie bitte unsere Einführung in Spring Web Services.

Integrationstests der REST-API in Spring Boot

Automatisierungstests sind die effizienteste Möglichkeit, Tests durchzuführen und dem Unternehmen Kosten zu sparen, indem der Personalaufwand reduziert wird. Dieses Tutorial zum Schreiben der REST-API für Integrationstests in der Spring Boot-Anwendung wird Ihnen auf jeden Fall dabei helfen, Ihre vorhandenen REST-Projekte in eine vollständig integrierte Testumgebung umzuwandeln.

Suchen Sie nach weiteren Tutorials zum Spring Framework? Besuchen Sie unsere besten Spring-Tutorials

Ich habe über die Erstellung von RESTful-Anwendungen geschrieben und diese auch mit dem Postman RESTful Client getestet. Aber im Idealfall müsste ich das Testen dieser RESTful-APIs automatisieren. In diesem Beitrag zeige ich Ihnen, wie Sie die Integrationstests für die REST-API mit Spring Boot genau durchführen. Ich habe den vollständigen Code in meinem Github geschrieben, Sie können darauf zugreifen, um weitere Details zur Implementierung zu erhalten.

Integrationstests der REST-API in Spring Boot

Zuerst müssen wir zum Testen entsprechende Abhängigkeiten in pom.xml hinzufügen, die unten angegeben sind:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-test</artifactId>
</dependency>

JUnit-Integrationstestklasse für die REST-API

Wir werden die Testklassen mithilfe der JUnit-Bibliothek schreiben. Sobald wir die Testklasse abgeschlossen haben, müssen wir diese Klasse in unserer Umgebung ausführen. Dies kann problemlos über IDEs wie Eclipse erfolgen, die die JUnit-Ausführung als integrierte Funktionalität unterstützen. Kommentieren wir die Controller-Testklasse wie unten gezeigt:

package app.controller;

import org.junit.runner.RunWith;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.WebIntegrationTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import app.Application;

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@WebIntegrationTest
public class BookControllerTest {

  //Required to Generate JSON content from Java objects
  public static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();

  //Required to delete the data added for tests.
  //Directly invoke the APIs interacting with the DB
  @Autowired
  private BookRepository bookRepository;

  //Test RestTemplate to invoke the APIs.
  private RestTemplate restTemplate = new TestRestTemplate();

}

Im obigen Code:

  • SpringJUnit4ClassRunner ist eine benutzerdefinierte Erweiterung von JUnits BlockJUnit4ClassRunner, die Funktionalität des Spring TestContext Framework bereitstellt.
  • @SpringApplicationConfiguration ist eine Annotation auf Klassenebene, die verwendet wird, um zu bestimmen, wie ein ApplicationContext für Integrationstests geladen und konfiguriert wird. Wir stellen ihm die Konfigurationsklasse zur Verfügung, die in diesem Fall lautet Application Klasse.
  • @WebIntegrationTest Anmerkung zur Testklasse, die angibt, dass es sich bei den Tests um „Web-Integrationstests“ handelt und daher wie bei einer Produktionsanwendung ein vollständiger Start erforderlich ist.

Außerdem müssen wir den Port angeben, an dem der Testserver laufen soll. Neben anderen Ansätzen bevorzuge ich die Erstellung eines application.properties Datei im Verzeichnis src/test/resources. Der Inhalt dieser Datei ist unten aufgeführt:

server.port = 8888

Mit dem obigen Setup können wir nun die APIs einzeln testen.

Testen der Create Book-API

Wie hier im API-Design für Creating Book angegeben, müssen wir den JSON im folgenden Format im Anforderungstext übergeben:

{
  "name" : "Book 3",
  "isbn": "45567",
  "author" : "Author 3",
  "pages" : 200
}

Unten finden Sie den Code zum Testen der Create-API:

@Test
public void testCreateBookApi() throws JsonProcessingException{

  //Building the Request body data
  Map<String, Object> requestBody = new HashMap<String, Object>();
  requestBody.put("name", "Book 1");
  requestBody.put("isbn", "QWER1234");
  requestBody.put("author", "Author 1");
  requestBody.put("pages", 200);
  HttpHeaders requestHeaders = new HttpHeaders();
  requestHeaders.setContentType(MediaType.APPLICATION_JSON);

  //Creating http entity object with request body and headers
  HttpEntity<String> httpEntity =
      new HttpEntity<String>(OBJECT_MAPPER.writeValueAsString(requestBody), requestHeaders);

  //Invoking the API
  Map<String, Object> apiResponse =
      restTemplate.postForObject("http://localhost:8888/book", httpEntity, Map.class, Collections.EMPTY_MAP);

  assertNotNull(apiResponse);

  //Asserting the response of the API.
  String message = apiResponse.get("message").toString();
  assertEquals("Book created successfully", message);
  String bookId = ((Map<String, Object>)apiResponse.get("book")).get("id").toString();

  assertNotNull(bookId);

  //Fetching the Book details directly from the DB to verify the API succeeded
  Book bookFromDb = bookRepository.findOne(bookId);
  assertEquals("Book 1", bookFromDb.getName());
  assertEquals("QWER1234", bookFromDb.getIsbn());
  assertEquals("Author 1", bookFromDb.getAuthor());
  assertTrue(200 == bookFromDb.getPages());

  //Delete the data added for testing
  bookRepository.delete(bookId);

}

Testen der API zum Abrufen von Buchdetails

Testen wir nun die API, die zum Abrufen der Buchdetails verwendet wird.

@Test
public void testGetBookDetailsApi(){
  //Create a new book using the BookRepository API
  Book book = new Book("Book1", "ÏSBN1", "Author1", 200);
  bookRepository.save(book);

  String bookId = book.getId();

  //Now make a call to the API to get details of the book
  Book apiResponse = restTemplate.getForObject("http://localhost:8888/book/"+ bookId, Book.class);

  //Verify that the data from the API and data saved in the DB are same
  assertNotNull(apiResponse);
  assertEquals(book.getName(), apiResponse.getName());
  assertEquals(book.getId(), apiResponse.getId());
  assertEquals(book.getIsbn(), apiResponse.getIsbn());
  assertEquals(book.getAuthor(), apiResponse.getAuthor());
  assertTrue(book.getPages() == apiResponse.getPages());

  //Delete the Test data created
  bookRepository.delete(bookId);
}

Testen der Update Book API

@Test
public void testUpdateBookDetails() throws JsonProcessingException{
  //Create a new book using the BookRepository API
  Book book = new Book("Book1", "ISBN1", "Author1", 200);
  bookRepository.save(book);

  String bookId = book.getId();

  //Now create Request body with the updated Book Data.
  Map<String, Object> requestBody = new HashMap<String, Object>();
  requestBody.put("name", "Book2");
  requestBody.put("isbn", "ISBN2");
  requestBody.put("author", "Author2");
  requestBody.put("pages", 200);
  HttpHeaders requestHeaders = new HttpHeaders();
  requestHeaders.setContentType(MediaType.APPLICATION_JSON);

  //Creating http entity object with request body and headers
  HttpEntity<String> httpEntity =
      new HttpEntity<String>(OBJECT_MAPPER.writeValueAsString(requestBody), requestHeaders);

  //Invoking the API
  Map<String, Object> apiResponse = (Map)restTemplate.exchange("http://localhost:8888/book/" + bookId,
      HttpMethod.PUT, httpEntity, Map.class, Collections.EMPTY_MAP).getBody();

  assertNotNull(apiResponse);
  assertTrue(!apiResponse.isEmpty());

  //Asserting the response of the API.
  String message = apiResponse.get("message").toString();
  assertEquals("Book Updated successfully", message);

  //Fetching the Book details directly from the DB to verify the API succeeded in updating the book details
  Book bookFromDb = bookRepository.findOne(bookId);
  assertEquals(requestBody.get("name"), bookFromDb.getName());
  assertEquals(requestBody.get("isbn"), bookFromDb.getIsbn());
  assertEquals(requestBody.get("author"), bookFromDb.getAuthor());
  assertTrue(Integer.parseInt(requestBody.get("pages").toString()) == bookFromDb.getPages());

  //Delete the data added for testing
  bookRepository.delete(bookId);

}

Testen der API zum Löschen von Büchern

@Test
public void testDeleteBookApi(){
  //Create a new book using the BookRepository API
  Book book = new Book("Book1", "ISBN1", "Author1", 200);
  bookRepository.save(book);

  String bookId = book.getId();

  //Now Invoke the API to delete the book
  restTemplate.delete("http://localhost:8888/book/"+ bookId, Collections.EMPTY_MAP);

  //Try to fetch from the DB directly
  Book bookFromDb = bookRepository.findOne(bookId);
  //and assert that there is no data found
  assertNull(bookFromDb);
}

Testen der Get All Books-API

@Test
public void testGetAllBooksApi(){
 //Add some test data for the API
 Book book1 = new Book("Book1", "ISBN1", "Author1", 200);
 bookRepository.save(book1);

 Book book2 = new Book("Book2", "ISBN2", "Author2", 200);
 bookRepository.save(book2);

 //Invoke the API
 Map<String, Object> apiResponse = restTemplate.getForObject("http://localhost:8888/book", Map.class);

 //Assert the response from the API
 int totalBooks = Integer.parseInt(apiResponse.get("totalBooks").toString());
 assertTrue(totalBooks == 2);

 List<Map<String, Object>> booksList = (List<Map<String, Object>>)apiResponse.get("books");
 assertTrue(booksList.size() == 2);

 //Delete the test data created
 bookRepository.delete(book1.getId());
 bookRepository.delete(book2.getId());
}

Die obigen Codebeispiele sind nur ein Teil der gesamten Beispiele. Auf meiner Github-Seite finden Sie die gesamte Beispielanwendung für REST-Integrationstests mit Spring Book. Wenn Sie Fragen haben, schreiben Sie diese bitte in den Kommentarbereich.

Ich hoffe, dieser Beitrag gibt Klarheit darüber, wie die REST-API für Integrationstests in der Spring Boot-Anwendung geschrieben wird. Diese Codebasis sowie der entsprechende REST-API-Code finden Sie auf GitHub Hier.

Kommentar verfassen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Nach oben scrollen