Übung Book Service Teil 2https://www.cmseo.ch/testfindallsorted?&atomFri, 29 Mar 2024 15:58:00 +0000stack.ch
https://stack.ch/
1dfa8b05-ede5-11ee-8c11-005056bb85fbSimtech AG - Ausbildung - Spring Boot/Angular Kurse - Kurs Spring Boot 3 - Kurs Spring Boot 3 - Ressourcen - Kurs Spring Boot - Ressourcen - Übung Book Service Teil 2
https://www.cmseo.ch/testfindallsorted
1dfa8c6c-ede5-11ee-8c11-005056bb85fbFri, 29 Mar 2024 15:58:00 +0000Übung Book Service Teil 2
https://www.cmseo.ch/testfindallsorted
1dfa8d9e-ede5-11ee-8c11-005056bb85fbFri, 29 Mar 2024 15:58:00 +0000
https://www.cmseo.ch/testfindallsorted
1dfa8e99-ede5-11ee-8c11-005056bb85fbFri, 29 Mar 2024 15:58:00 +0000Erstellen Sie das BookRepository für den Spring Data Zugriff auf die Book Entity z.B. wie folgt:package ch.std.book.repositories;
import java.util.List;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import ch.std.book.jpa.Book;
public interface BookRepository extends JpaRepository<Book, Long> {
Optional<Book> findById(Long id);
Optional<Book> findByIsbn(String isbn);
List<Book> findByTitle(String text);
List<Book> findByTitleContaining(String text);
List<Book> findByTitleContainingIgnoreCase(String text);
List<Book> findByTitleStartingWith(String text);
List<Book> findByTitleEndingWith(String text);
@Query("SELECT b FROM Book b WHERE b.isbn LIKE %:text% OR b.title LIKE %:text% OR b.description LIKE %:text% OR b.publisher LIKE %:text%")
List<Book> findAllContaining(@Param("text") String text);
// Experimentieren Sie mit weiteren Varianten
}Wichtig: Starten Sie nach jeder Anpassung der Repositories die Anwendung und verifizieren Sie ob solche korrekt startet.
https://www.cmseo.ch/testfindallsorted
1dfa93aa-ede5-11ee-8c11-005056bb85fbFri, 29 Mar 2024 15:58:00 +0000Wir beginnen mit der Programmierung des ersten Unit Tests für dieses Projekt. Hierzu arbeiten wir mit dem Profile "unittest" und erstellen die Datei application-unittest.properties im test/resources Verzeichnis wie folgt:book.scheduler.initial.enabled=false
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driver-class-name=org.h2.Driver
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect
spring.jpa.database-platform=org.hibernate.dialect.H2DialectProgrammieren Sie im test/java-Folder die Klasse ch.std.book.repositories.BookRepositoryJPATest:package ch.std.book.repositories;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit.jupiter.SpringExtension;
@ExtendWith(SpringExtension.class)
@DataJpaTest
@ActiveProfiles("unittest")
public class BookRepositoryJPATest {
@BeforeEach
public void setup() {
}
@Test
public void testFindById() {
}
@Test
public void testFindByIsbn() {
}
@Test
public void testFindAll() {
}
@Test
public void testFindAllSorted() {
}
@Test
public void testFindByTitle() {
}
@Test
public void testFindByTitleContaining() {
}
@Test
public void testFindByTitleContainingIgnoringCase() {
}
@Test
public void testFindAllContaining() {
}
}@DataJpaTest Klassen verwenden die H2 Datenbank. Damit wir solche benutzen können benötigen wir die folgende Maven Dependency:<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>Das schwierigste an der Programmierung der Unit Tests ist das Aufsetzen der Testdaten. Solche werden in der Regel über die Setup-Methode und die Annotation @BeforeEach aufgebaut und je nach Use Case mit der Methode markiert mit @AfterEach wieder abgebaut. Das folgende Listing zeigt den möglichen Setup für die Testdaten:...
@ExtendWith(SpringExtension.class)
@DataJpaTest
@ActiveProfiles("unittest") // alternativ kann mit der @TestPropertySource Annotation gearbeitet werden
public class BookRepositoryJPATest {
@Autowired
private BookRepository bookRepository;
private Book book;
private List<Book> bookList;
@BeforeEach
public void setup() {
book = new Book("978-1617292545", "this is the title", "that's the description", "my publisher");
this.bookRepository.save(book);
// insert more books
this.bookList = new ArrayList<>();
for (int i = 0; i < 10; i++) {
Book localBook = null;
if (i % 2 == 0) {
localBook = new Book("isbn-" + i, "title-" + i, "description-" + i, "publisher-" + i);
} else {
localBook = new Book("isbn-".toUpperCase() + i, "title-".toUpperCase() + i,
"description-".toUpperCase() + i, "publisher-".toUpperCase() + i);
}
this.bookRepository.save(localBook);
this.bookList.add(localBook);
}
}
@AfterEach
public void tearDown() {
this.bookRepository.deleteAllInBatch();
}
// ...
}Das Beispiel erwartet weitere Konstruktoren in der Klasse Book.Programmieren Sie die Unit Tests so aus, dass solche Sinn und Zweck erfüllen. Testen Sie auch die restlichen BookRepository Methoden, sofern Sie solche programmiert haben.Eine Musterlösung finden Sie unter BookRepositoryJPATest.java.
https://www.cmseo.ch/testfindallsorted
1dfaa03e-ede5-11ee-8c11-005056bb85fbFri, 29 Mar 2024 15:58:00 +0000Erstellen Sie die Klasse BookController als Rest Service und implementieren Sie die Methoden gemäss der Vorlage:package ch.std.book.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import ch.std.book.jpa.Book;
import ch.std.book.repositories.BookRepository;
@RestController
public class BookController {
BookRepository bookRepository;
public BookController(BookRepository bookRepository) {
this.bookRepository = bookRepository;
}
@GetMapping("/rest/books")
public Book[] getBooks(@RequestParam(value = "value", required = false) String value) {
}
@GetMapping("/rest/book/{id}")
public Book getBookById(@PathVariable Long id) {
}
@GetMapping("/rest/book")
public Book getBookByIsbn(@RequestParam String isbn) {
}
@PostMapping("/rest/book")
public Book createBook(@RequestBody Book book) {
}
@PutMapping("/rest/book/{id}")
public Book updateBook(@RequestBody Book book, @PathVariable Long id) {
}
@DeleteMapping("/rest/book/{id}")
public ResponseEntity<?> deleteBookById(@PathVariable Long id) {
}
public static class BookNotFoundException extends RuntimeException {
}
}Programmieren Sie die Methoden so aus, dass die Daten aus der Datenbank gelesen und geschrieben werden gemäss Anforderung. Definieren Sie noch den Server Context inkl. Port in der Datei application.properties z.B. wie folgt:server.port=8080
server.servlet.context-path=/bookStarten Sie die Applikation und testen Sie ob die Bücher geladen werden:
https://www.cmseo.ch/testfindallsorted
1dfaac57-ede5-11ee-8c11-005056bb85fbFri, 29 Mar 2024 15:58:00 +0000Erstellen Sie die Klasse BookControllerTest und implementieren Sie die Methoden gemäss der Vorlage:package ch.std.book.integration;
import java.util.ArrayList;
import java.util.List;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.http.HttpEntity;
import org.springframework.test.context.ActiveProfiles;
import ch.std.book.jpa.Book;
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@ActiveProfiles("unittest")
public class BookControllerTests {
Logger logger = LoggerFactory.getLogger(BookControllerTests.class);
@Autowired
private TestRestTemplate restTemplate;
private List<Book> bookList = new ArrayList<>();
@BeforeEach public void setup() {
logger.info("BookControllerTests.setup");
this.bookList.clear();
// create test book
String postUrl = "/rest/book";
HttpEntity request = new HttpEntity<>(new Book("1234567890","test", "test", "test"));
logger.info("BookControllerTests.setup, postUrl = " + postUrl);
Book testBook = this.restTemplate.postForObject(postUrl, request, Book.class);
logger.info("BookControllerTests.setup, testBook = " + testBook);
this.bookList.add(testBook);
}
@Test public void testGetBooks() throws Exception { }
@Test public void testGetAllBooks() throws Exception { }
@Test public void testGetBookById() throws Exception { }
}Sie können sich an der Klasse CityControllerTests orientieren.
https://www.cmseo.ch/testfindallsorted
1dfab14a-ede5-11ee-8c11-005056bb85fbFri, 29 Mar 2024 15:58:00 +0000Eine mögliche Lösung finden Sie als Maven Projekt bookservice2.zipÜber uns
https://www.cmseo.ch/about
Fri, 29 Mar 2024 15:58:00 +00001dfabb99-ede5-11ee-8c11-005056bb85fbAktuell
https://www.cmseo.ch/
Fri, 29 Mar 2024 15:58:00 +00001dfabd62-ede5-11ee-8c11-005056bb85fbAGB
https://www.cmseo.ch/agb
Fri, 29 Mar 2024 15:58:00 +00001dfabeff-ede5-11ee-8c11-005056bb85fbBildungswege
https://www.cmseo.ch/bildungswege
Fri, 29 Mar 2024 15:58:00 +00001dfac0c9-ede5-11ee-8c11-005056bb85fbBlog
https://www.cmseo.ch/blog
Fri, 29 Mar 2024 15:58:00 +00001dfac244-ede5-11ee-8c11-005056bb85fbRufen Sie mich an
https://www.cmseo.ch/callus
Fri, 29 Mar 2024 15:58:00 +00001dfac369-ede5-11ee-8c11-005056bb85fbCharts
https://www.cmseo.ch/charts
Fri, 29 Mar 2024 15:58:00 +00001dfac518-ede5-11ee-8c11-005056bb85fbConsulting
https://www.cmseo.ch/consulting
Fri, 29 Mar 2024 15:58:00 +00001dfac6b5-ede5-11ee-8c11-005056bb85fbKontakt
https://www.cmseo.ch/contact
Fri, 29 Mar 2024 15:58:00 +00001dfac837-ede5-11ee-8c11-005056bb85fbAusbildung/Kurse
https://www.cmseo.ch/education
Fri, 29 Mar 2024 15:58:00 +00001dfac975-ede5-11ee-8c11-005056bb85fbSoftware Engineering
https://www.cmseo.ch/engineering
Fri, 29 Mar 2024 15:58:00 +00001dfaca98-ede5-11ee-8c11-005056bb85fbFreelancer
https://www.cmseo.ch/freelancer
Fri, 29 Mar 2024 15:58:00 +00001dfacbd9-ede5-11ee-8c11-005056bb85fbImpressum
https://www.cmseo.ch/impressum
Fri, 29 Mar 2024 15:58:00 +00001dfaccfa-ede5-11ee-8c11-005056bb85fbKursleiter
https://www.cmseo.ch/kursleiter
Fri, 29 Mar 2024 15:58:00 +00001dface28-ede5-11ee-8c11-005056bb85fbNetzwerk
https://www.cmseo.ch/network
Fri, 29 Mar 2024 15:58:00 +00001dfacf5d-ede5-11ee-8c11-005056bb85fbReferenzen
https://www.cmseo.ch/references
Fri, 29 Mar 2024 15:58:00 +00001dfad0ac-ede5-11ee-8c11-005056bb85fbSitemap
https://www.cmseo.ch/sitemap
Fri, 29 Mar 2024 15:58:00 +00001dfad225-ede5-11ee-8c11-005056bb85fbTools
https://www.cmseo.ch/tools
Fri, 29 Mar 2024 15:58:00 +00001dfad41c-ede5-11ee-8c11-005056bb85fbVision
https://www.cmseo.ch/vision
Fri, 29 Mar 2024 15:58:00 +00001dfad54c-ede5-11ee-8c11-005056bb85fb