diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index f4a6e96f..f8f3b6af 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -1,68 +1,30 @@ -name: Build Maven Projects +name: Build Maven Projects (Java 8, 11, 17) + on: push: schedule: - cron: '0 5 * * SUN' + jobs: - build-java-8-and-17-projects: + build-java-8-11-17-projects: strategy: fail-fast: false matrix: - versions: [8, 17] - runs-on: ubuntu-20.04 + versions: [8, 11, 17] + runs-on: ubuntu-latest name: Build Java ${{ matrix.versions }} projects steps: - name: VCS checkout - uses: actions/checkout@v1 - - - name: Set up cache - uses: actions/cache@v1 - with: - path: ~/.m2/repository - key: ${{ runner.os }}-maven-jdk${{ matrix.versions }}-${{ hashFiles('**/pom.xml') }} - restore-keys: | - ${{ runner.os }}-maven-jdk${{ matrix.versions }}- + uses: actions/checkout@v4 - name: Set up JDK ${{ matrix.versions }} - uses: actions/setup-java@v2 + uses: actions/setup-java@v4 with: java-version: ${{ matrix.versions }} - distribution: 'adopt' - java-package: 'jdk' + distribution: adopt + cache: maven - name: Build all projects with Maven run: | chmod +x ./buildJdk${{ matrix.versions }}Projects.sh ./buildJdk${{ matrix.versions }}Projects.sh - - build-java-11-project-batches: - strategy: - fail-fast: false - matrix: - batch: [1, 2, 3] - runs-on: ubuntu-20.04 - name: Build Java 11 Batch ${{ matrix.batch }} projects - steps: - - name: VCS checkout - uses: actions/checkout@v1 - - - name: Set up cache - uses: actions/cache@v1 - with: - path: ~/.m2/repository - key: ${{ runner.os }}-maven-jdk${{ matrix.batch }}-${{ hashFiles('**/pom.xml') }} - restore-keys: | - ${{ runner.os }}-maven-jdk${{ matrix.batch }}- - - - name: Set up JDK $11 - uses: actions/setup-java@v2 - with: - java-version: 11 - distribution: 'adopt' - java-package: 'jdk' - - - name: Build all projects of batch with Maven - run: | - chmod +x ./buildJdk11Projects_0${{ matrix.batch }}.sh - ./buildJdk11Projects_0${{ matrix.batch }}.sh - \ No newline at end of file diff --git a/.github/workflows/sampleJavaMavenProject.yml b/.github/workflows/sampleJavaMavenProject.yml index c76b6efb..15221aaa 100644 --- a/.github/workflows/sampleJavaMavenProject.yml +++ b/.github/workflows/sampleJavaMavenProject.yml @@ -4,45 +4,43 @@ on: [push] jobs: compile: - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest strategy: matrix: - java: [ 11, 12, 13 ] + java: [ 21 ] name: Java ${{ matrix.java }} compile steps: - name: Checkout Source Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 + - name: Setup Java - uses: actions/setup-java@v2 + uses: actions/setup-java@v3 with: distribution: 'adopt' java-package: jdk java-version: ${{ matrix.java }} + - name: Compile the Project - working-directory: github-actions-java-maven - run: mvn -B compile + run: ./mvnw -f github-actions-java-maven/pom.xml -B compile build: - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest needs: compile name: Build the Maven Project steps: - - uses: actions/checkout@v2 - - uses: actions/cache@v2 - with: - path: ~/.m2/repository - key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} - restore-keys: | - ${{ runner.os }}-maven- - - name: Set up JDK 11 - uses: actions/setup-java@v2 + - uses: actions/checkout@v3 + + - name: Set up JDK 21 + uses: actions/setup-java@v3 with: distribution: 'adopt' - java-version: '11' + java-version: '21' java-package: jdk + cache: 'maven' + - name: Build and test project - working-directory: github-actions-java-maven - run: mvn -B verify + run: ./mvnw -f github-actions-java-maven/pom.xml -B verify + - name: Upload Maven build artifact uses: actions/upload-artifact@v2 with: @@ -50,16 +48,18 @@ jobs: path: github-actions-java-maven/target/github-actions-java-maven.jar deploy: - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest needs: build name: Build Docker Container and Deploy to Kubernetes steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 + - name: Download Maven build artifact uses: actions/download-artifact@v2 with: name: artifact.jar path: github-actions-java-maven/target + - name: Build Docker container working-directory: github-actions-java-maven run: | @@ -68,7 +68,9 @@ jobs: env: SUPER_SECRET: ${{ secrets.SUPER_SECRET }} run: echo "Content of secret - $SUPER_SECRET" + - name: Push Docker images run: echo "Pushing Docker image to Container Registry (e.g. ECR)" + - name: Deploy application run: echo "Deploying application (e.g. Kubernetes)" diff --git a/.gitignore b/.gitignore index ff7f85be..a16d634f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ .DS_Store .idea -*.iml \ No newline at end of file +*.iml +*.bak +target +spotless-index diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 00000000..8d6805cf --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,17 @@ +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.5.0 + hooks: + - id: check-yaml + - id: end-of-file-fixer + - id: trailing-whitespace + - repo: https://github.com/Lucas-C/pre-commit-hooks + rev: v1.5.4 + hooks: + - id: forbid-crlf + - id: remove-crlf + - repo: https://github.com/ejba/pre-commit-maven + rev: v0.3.4 + hooks: + - id: maven + args: ['-f pom.xml spotless:apply'] diff --git a/avoid-repeating-attributes-in-jpa-entities/pom.xml b/avoid-repeating-attributes-in-jpa-entities/pom.xml index c53baf06..5cead406 100644 --- a/avoid-repeating-attributes-in-jpa-entities/pom.xml +++ b/avoid-repeating-attributes-in-jpa-entities/pom.xml @@ -3,7 +3,13 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - de.blog.rieckpil + + de.rieckpil.blog + blog-parent + 0.0.1-SNAPSHOT + ../pom.xml + + avoid-repeating-attributes-in-jpa-entities 0.0.1-SNAPSHOT jar @@ -11,19 +17,6 @@ avoid-repeating-attributes-in-jpa-entities Demo project fo avoiding repeated attributes in JPA entities - - org.springframework.boot - spring-boot-starter-parent - 2.3.0.RELEASE - - - - - UTF-8 - UTF-8 - 11 - - org.springframework.boot diff --git a/avoid-repeating-attributes-in-jpa-entities/src/main/java/de/blog/rieckpil/BaseEnterpriseEntity.java b/avoid-repeating-attributes-in-jpa-entities/src/main/java/de/blog/rieckpil/BaseEnterpriseEntity.java index 41671bb2..5fdf2ed5 100644 --- a/avoid-repeating-attributes-in-jpa-entities/src/main/java/de/blog/rieckpil/BaseEnterpriseEntity.java +++ b/avoid-repeating-attributes-in-jpa-entities/src/main/java/de/blog/rieckpil/BaseEnterpriseEntity.java @@ -1,13 +1,12 @@ package de.blog.rieckpil; +import jakarta.persistence.*; +import java.time.LocalDateTime; +import java.util.concurrent.ThreadLocalRandom; import lombok.Data; import org.hibernate.annotations.CreationTimestamp; import org.hibernate.annotations.UpdateTimestamp; -import javax.persistence.*; -import java.time.LocalDateTime; -import java.util.concurrent.ThreadLocalRandom; - @Data @MappedSuperclass public class BaseEnterpriseEntity { @@ -18,15 +17,12 @@ public class BaseEnterpriseEntity { private String internId; - @CreationTimestamp - private LocalDateTime createdAt; + @CreationTimestamp private LocalDateTime createdAt; - @UpdateTimestamp - private LocalDateTime updatedAt; + @UpdateTimestamp private LocalDateTime updatedAt; @PrePersist public void prePersist() { this.internId = String.valueOf(Math.abs(ThreadLocalRandom.current().nextInt())); } - } diff --git a/avoid-repeating-attributes-in-jpa-entities/src/main/java/de/blog/rieckpil/Customer.java b/avoid-repeating-attributes-in-jpa-entities/src/main/java/de/blog/rieckpil/Customer.java index cef6ae4d..38ff57fc 100644 --- a/avoid-repeating-attributes-in-jpa-entities/src/main/java/de/blog/rieckpil/Customer.java +++ b/avoid-repeating-attributes-in-jpa-entities/src/main/java/de/blog/rieckpil/Customer.java @@ -1,10 +1,9 @@ package de.blog.rieckpil; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; import lombok.Data; -import javax.persistence.Column; -import javax.persistence.Entity; - @Data @Entity public class Customer extends BaseEnterpriseEntity { @@ -14,5 +13,4 @@ public class Customer extends BaseEnterpriseEntity { @Column(nullable = false, length = 40) private String customerId; - } diff --git a/avoid-repeating-attributes-in-jpa-entities/src/main/java/de/blog/rieckpil/CustomerRepository.java b/avoid-repeating-attributes-in-jpa-entities/src/main/java/de/blog/rieckpil/CustomerRepository.java index 6379cdb0..11741861 100644 --- a/avoid-repeating-attributes-in-jpa-entities/src/main/java/de/blog/rieckpil/CustomerRepository.java +++ b/avoid-repeating-attributes-in-jpa-entities/src/main/java/de/blog/rieckpil/CustomerRepository.java @@ -2,5 +2,4 @@ import org.springframework.data.jpa.repository.JpaRepository; -public interface CustomerRepository extends JpaRepository { -} +public interface CustomerRepository extends JpaRepository {} diff --git a/avoid-repeating-attributes-in-jpa-entities/src/main/java/de/blog/rieckpil/DatabaseFiller.java b/avoid-repeating-attributes-in-jpa-entities/src/main/java/de/blog/rieckpil/DatabaseFiller.java index 5732ce8f..2333239b 100644 --- a/avoid-repeating-attributes-in-jpa-entities/src/main/java/de/blog/rieckpil/DatabaseFiller.java +++ b/avoid-repeating-attributes-in-jpa-entities/src/main/java/de/blog/rieckpil/DatabaseFiller.java @@ -9,7 +9,8 @@ public class DatabaseFiller implements CommandLineRunner { private final CustomerRepository customerRepository; private final ProductRepository productRepository; - public DatabaseFiller(CustomerRepository customerRepository, ProductRepository productRepository) { + public DatabaseFiller( + CustomerRepository customerRepository, ProductRepository productRepository) { this.customerRepository = customerRepository; this.productRepository = productRepository; } diff --git a/avoid-repeating-attributes-in-jpa-entities/src/main/java/de/blog/rieckpil/Product.java b/avoid-repeating-attributes-in-jpa-entities/src/main/java/de/blog/rieckpil/Product.java index 326f6e2a..b6c52cf7 100644 --- a/avoid-repeating-attributes-in-jpa-entities/src/main/java/de/blog/rieckpil/Product.java +++ b/avoid-repeating-attributes-in-jpa-entities/src/main/java/de/blog/rieckpil/Product.java @@ -1,10 +1,9 @@ package de.blog.rieckpil; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; import lombok.Data; -import javax.persistence.Column; -import javax.persistence.Entity; - @Data @Entity public class Product extends BaseEnterpriseEntity { @@ -13,5 +12,4 @@ public class Product extends BaseEnterpriseEntity { private String name; private int amount; - } diff --git a/avoid-repeating-attributes-in-jpa-entities/src/main/java/de/blog/rieckpil/ProductRepository.java b/avoid-repeating-attributes-in-jpa-entities/src/main/java/de/blog/rieckpil/ProductRepository.java index e2ebb360..c221fd80 100644 --- a/avoid-repeating-attributes-in-jpa-entities/src/main/java/de/blog/rieckpil/ProductRepository.java +++ b/avoid-repeating-attributes-in-jpa-entities/src/main/java/de/blog/rieckpil/ProductRepository.java @@ -2,5 +2,4 @@ import org.springframework.data.jpa.repository.JpaRepository; -public interface ProductRepository extends JpaRepository { -} +public interface ProductRepository extends JpaRepository {} diff --git a/avoid-repeating-attributes-in-jpa-entities/src/test/java/de/blog/rieckpil/ApplicationTests.java b/avoid-repeating-attributes-in-jpa-entities/src/test/java/de/blog/rieckpil/ApplicationTests.java index 800d03e8..27f24288 100644 --- a/avoid-repeating-attributes-in-jpa-entities/src/test/java/de/blog/rieckpil/ApplicationTests.java +++ b/avoid-repeating-attributes-in-jpa-entities/src/test/java/de/blog/rieckpil/ApplicationTests.java @@ -7,7 +7,5 @@ public class ApplicationTests { @Test - public void contextLoads() { - } - + public void contextLoads() {} } diff --git a/buildJdk11Projects_01.sh b/buildJdk11Projects.sh similarity index 52% rename from buildJdk11Projects_01.sh rename to buildJdk11Projects.sh index 022729b1..fcd2d39d 100755 --- a/buildJdk11Projects_01.sh +++ b/buildJdk11Projects.sh @@ -5,30 +5,31 @@ set -o pipefail mvn -B -f consumer-driven-contracts-with-spring-cloud-contract/book-store-server install -declare -a arr=("whats-new-in-spring-boot-2.1" +declare -a arr=( "charts-in-pdf-java-ee" - "avoid-repeating-attributes-in-jpa-entities" "java-benchmarking-with-jmh" - "lazy-loading-of-jpa-attributes-with-hibernate" "graalvm-intro" - "send-emails-with-sendgrid-and-spring-boot" "bootstrap-jakarta-ee-8-application" "custom-maven-archetype" - "demo-crud-application" - "dynamic-sql-querying-with-pagination" - "deploy-spring-boot-to-gke" - "spring-boot-hibernate-flyway-best-practices" "guide-to-jakarta-ee-with-react-and-postgresql" "five-java-9-features" "consumer-driven-contracts-with-spring-cloud-contract/book-store-client" "java-ee-with-kotlin" - "spring-boot-with-kotlin" - "difference-between-mock-and-mockbean" - "spring-boot-override-test-properties" "test-java-http-clients" - "spring-boot-test-mail-sending" - "spring-boot-shedlock" - "spring-data-mongo-test-testcontainers" + "telegram-bot-notifications-with-java" + "websockets-with-jakarta-ee" + "open-liberty-maven-plugin-review" + "jakarta-ee-react-file-handling" + "review-microshed-testing" + "whats-new-in-microprofile-3.1" + "serverless-java-aws-examples/thumbnail-generator" + "serverless-java-aws-examples/spring-cloud-function-aws" + "serverless-java-aws-examples/spring-cloud-function-kotlin-aws" + "five-unknown-junit-5-features" + "mockito-tips-and-tricks" + "testing-libraries-overview" + "testing-java-applications-with-maven" + "open-rewrite-example" ) for project in "${arr[@]}" diff --git a/buildJdk11Projects_02.sh b/buildJdk11Projects_02.sh deleted file mode 100755 index 69287bac..00000000 --- a/buildJdk11Projects_02.sh +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/bash - -set -e -set -o pipefail - -declare -a arr=( - "spring-boot-integration-tests-testcontainers" - "telegram-bot-notifications-with-java" - "websockets-with-jakarta-ee" - "open-liberty-maven-plugin-review" - "jakarta-ee-react-file-handling" - "remote-debugging-spring-boot-application" - "review-microshed-testing" - "maven-plugins-to-ensure-quality" - "spring-web-client-demo" - "spring-boot-uploading-and-downloading-files-with-react" - "spring-web-client-oauth2-reactive-stack" - "spring-web-client-oauth2-servlet-stack" - "spring-web-test-client" - "spring-web-client-customizing" - "spring-web-client-testing-with-mockwebserver" - "spring-web-client-exchange-retrieve" - "whats-new-in-microprofile-3.1" - "whats-new-in-spring-boot-2.1" - "whats-new-in-spring-boot-2.2" - "spring-web-test-client" - "github-actions-java-maven" -) - -for project in "${arr[@]}" -do - mvn -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -f $project/pom.xml verify -done diff --git a/buildJdk11Projects_03.sh b/buildJdk11Projects_03.sh deleted file mode 100755 index 242c1f68..00000000 --- a/buildJdk11Projects_03.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/bin/bash - -set -e -set -o pipefail - -declare -a arr=( - "spring-web-client-expose-metrics" - "spring-boot-selenium-integration-tests" - "testing-json-serialization-spring" - "spring-web-mvc-cheat-sheet" - "spring-boot-aws-ssm-parameter-resolving" - "expose-git-information-actuator" - "serverless-java-aws-examples/thumbnail-generator" - "serverless-java-aws-examples/spring-cloud-function-aws" - "serverless-java-aws-examples/spring-cloud-function-kotlin-aws" - "spring-security-aws-cognito-thymeleaf" - "testcontainers-reuse-existing-containers" - "five-unknown-junit-5-features" - "spring-test-context-caching-introduction" - "spring-boot-kotlin-testcontainers" - "dependency-version-update-plugin" - "testing-spring-boot-applications-with-mockmvc" - "mockito-tips-and-tricks" - "write-concise-web-tests-with-selenide" - "testing-libraries-overview" - "spring-boot-test-spring-events" - "spring-boot-testing-tips-and-tricks" - "testing-java-applications-with-maven" - "open-rewrite-example" -) - -for project in "${arr[@]}" -do - mvn -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -f $project/pom.xml verify -done diff --git a/buildJdk17Projects.sh b/buildJdk17Projects.sh index 09b81ae7..d15b0787 100644 --- a/buildJdk17Projects.sh +++ b/buildJdk17Projects.sh @@ -4,14 +4,9 @@ set -e set -o pipefail declare -a arr=( - "testing-spring-rest-template" - "serverless-java-aws-examples/java-aws-lambda-custom-image" - "launchdarkly-java-development-testing-hints" - "random-data-in-java-using-java-faker" - "testcontainers-introduction" "maven-junit-paralellize-tests" ) diff --git a/buildJdk8Projects.sh b/buildJdk8Projects.sh index b6db4dc9..374c2f66 100755 --- a/buildJdk8Projects.sh +++ b/buildJdk8Projects.sh @@ -3,7 +3,8 @@ set -e set -o pipefail -declare -a arr=("rest-easy-file-uploading-and-downloading" +declare -a arr=( + "rest-easy-file-uploading-and-downloading" "generate-documents-from-word-templates-with-docx4j-on-wildfly14" "hello-world-jsf-2.3" "embedded-messaging-engine-open-liberty" @@ -16,7 +17,6 @@ declare -a arr=("rest-easy-file-uploading-and-downloading" "jax-rs-api-rate-limiting-with-jsr-375" "jpa-integration-tests-java-ee" "jsf-simple-login-with-java-ee-security-api" - "load-testing-your-application" "messaging-with-jms-using-payara" "microprofile-jwt-keycloak-auth/backend" "microprofile-rest-client-for-restful-communication/order-application" diff --git a/demo-crud-application/pom.xml b/demo-crud-application/pom.xml index 6f68afef..dc91f98e 100644 --- a/demo-crud-application/pom.xml +++ b/demo-crud-application/pom.xml @@ -2,22 +2,19 @@ 4.0.0 + - org.springframework.boot - spring-boot-starter-parent - 2.2.2.RELEASE - + de.rieckpil.blog + blog-parent + 0.0.1-SNAPSHOT + ../pom.xml - de.rieckpil.blog + demo-crud-application 0.0.1-SNAPSHOT demo-crud-application Demo project for Spring Boot - - 11 - - org.springframework.boot @@ -27,6 +24,10 @@ org.springframework.boot spring-boot-starter-web + + org.springframework.boot + spring-boot-starter-validation + com.github.javafaker javafaker diff --git a/demo-crud-application/src/main/java/de/rieckpil/blog/Book.java b/demo-crud-application/src/main/java/de/rieckpil/blog/Book.java index a9eebb8a..a7fc3282 100644 --- a/demo-crud-application/src/main/java/de/rieckpil/blog/Book.java +++ b/demo-crud-application/src/main/java/de/rieckpil/blog/Book.java @@ -1,19 +1,16 @@ package de.rieckpil.blog; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; import lombok.Data; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; - @Data @Entity public class Book { - @Id - @GeneratedValue - private Long id; + @Id @GeneratedValue private Long id; @Column(nullable = false, unique = true) private String isbn; @@ -23,5 +20,4 @@ public class Book { @Column(nullable = false) private String author; - } diff --git a/demo-crud-application/src/main/java/de/rieckpil/blog/BookController.java b/demo-crud-application/src/main/java/de/rieckpil/blog/BookController.java index c130384b..4b7f2bb0 100644 --- a/demo-crud-application/src/main/java/de/rieckpil/blog/BookController.java +++ b/demo-crud-application/src/main/java/de/rieckpil/blog/BookController.java @@ -1,5 +1,7 @@ package de.rieckpil.blog; +import jakarta.validation.Valid; +import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; @@ -8,21 +10,19 @@ import org.springframework.web.util.UriComponents; import org.springframework.web.util.UriComponentsBuilder; -import javax.validation.Valid; -import java.util.List; - @RestController @RequestMapping("/api/books") public class BookController { - @Autowired - private BookService bookService; + @Autowired private BookService bookService; @PostMapping - public ResponseEntity createNewBook(@Valid @RequestBody BookRequest bookRequest, UriComponentsBuilder uriComponentsBuilder) { + public ResponseEntity createNewBook( + @Valid @RequestBody BookRequest bookRequest, UriComponentsBuilder uriComponentsBuilder) { Long primaryKey = bookService.createNewBook(bookRequest); - UriComponents uriComponents = uriComponentsBuilder.path("/api/books/{id}").buildAndExpand(primaryKey); + UriComponents uriComponents = + uriComponentsBuilder.path("/api/books/{id}").buildAndExpand(primaryKey); HttpHeaders headers = new HttpHeaders(); headers.setLocation(uriComponents.toUri()); @@ -40,7 +40,8 @@ public ResponseEntity getBookById(@PathVariable("id") Long id) { } @PutMapping("/{id}") - public ResponseEntity updateBook(@PathVariable("id") Long id, @Valid @RequestBody BookRequest bookRequest) { + public ResponseEntity updateBook( + @PathVariable("id") Long id, @Valid @RequestBody BookRequest bookRequest) { return ResponseEntity.ok(bookService.updateBook(id, bookRequest)); } @@ -49,5 +50,4 @@ public ResponseEntity deleteBook(@PathVariable("id") Long id) { bookService.deleteBookById(id); return ResponseEntity.ok().build(); } - } diff --git a/demo-crud-application/src/main/java/de/rieckpil/blog/BookInitializer.java b/demo-crud-application/src/main/java/de/rieckpil/blog/BookInitializer.java index e587020d..8af7329f 100644 --- a/demo-crud-application/src/main/java/de/rieckpil/blog/BookInitializer.java +++ b/demo-crud-application/src/main/java/de/rieckpil/blog/BookInitializer.java @@ -1,19 +1,17 @@ package de.rieckpil.blog; import com.github.javafaker.Faker; +import java.util.UUID; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.stereotype.Component; -import java.util.UUID; - @Slf4j @Component public class BookInitializer implements CommandLineRunner { - @Autowired - private BookRepository bookRepository; + @Autowired private BookRepository bookRepository; @Override public void run(String... args) throws Exception { @@ -33,6 +31,5 @@ public void run(String... args) throws Exception { } log.info("... finished book initialization"); - } } diff --git a/demo-crud-application/src/main/java/de/rieckpil/blog/BookRepository.java b/demo-crud-application/src/main/java/de/rieckpil/blog/BookRepository.java index 7ce6e9b7..e6506dcd 100644 --- a/demo-crud-application/src/main/java/de/rieckpil/blog/BookRepository.java +++ b/demo-crud-application/src/main/java/de/rieckpil/blog/BookRepository.java @@ -2,5 +2,4 @@ import org.springframework.data.jpa.repository.JpaRepository; -public interface BookRepository extends JpaRepository { -} +public interface BookRepository extends JpaRepository {} diff --git a/demo-crud-application/src/main/java/de/rieckpil/blog/BookRequest.java b/demo-crud-application/src/main/java/de/rieckpil/blog/BookRequest.java index 1cbcf21b..06905054 100644 --- a/demo-crud-application/src/main/java/de/rieckpil/blog/BookRequest.java +++ b/demo-crud-application/src/main/java/de/rieckpil/blog/BookRequest.java @@ -1,20 +1,17 @@ package de.rieckpil.blog; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.Size; import lombok.Data; -import javax.validation.constraints.NotEmpty; -import javax.validation.constraints.Size; - @Data public class BookRequest { - @NotEmpty - private String title; + @NotEmpty private String title; @NotEmpty @Size(max = 20) private String isbn; - @NotEmpty - private String author; + @NotEmpty private String author; } diff --git a/demo-crud-application/src/main/java/de/rieckpil/blog/BookService.java b/demo-crud-application/src/main/java/de/rieckpil/blog/BookService.java index cf3576dd..3e8598b9 100644 --- a/demo-crud-application/src/main/java/de/rieckpil/blog/BookService.java +++ b/demo-crud-application/src/main/java/de/rieckpil/blog/BookService.java @@ -1,17 +1,15 @@ package de.rieckpil.blog; +import java.util.List; +import java.util.Optional; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.util.List; -import java.util.Optional; - @Service public class BookService { - @Autowired - private BookRepository bookRepository; + @Autowired private BookRepository bookRepository; public Long createNewBook(BookRequest bookRequest) { Book book = new Book(); diff --git a/demo-crud-application/src/main/java/de/rieckpil/blog/DemoCrudApplication.java b/demo-crud-application/src/main/java/de/rieckpil/blog/DemoCrudApplication.java index a737cde5..0963e587 100644 --- a/demo-crud-application/src/main/java/de/rieckpil/blog/DemoCrudApplication.java +++ b/demo-crud-application/src/main/java/de/rieckpil/blog/DemoCrudApplication.java @@ -9,5 +9,4 @@ public class DemoCrudApplication { public static void main(String[] args) { SpringApplication.run(DemoCrudApplication.class, args); } - } diff --git a/demo-crud-application/src/test/java/de/rieckpil/blog/BookControllerIT.java b/demo-crud-application/src/test/java/de/rieckpil/blog/BookControllerIT.java index f5aee301..99e99f4f 100644 --- a/demo-crud-application/src/test/java/de/rieckpil/blog/BookControllerIT.java +++ b/demo-crud-application/src/test/java/de/rieckpil/blog/BookControllerIT.java @@ -1,26 +1,24 @@ package de.rieckpil.blog; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; + import com.fasterxml.jackson.databind.JsonNode; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.test.context.junit.jupiter.SpringExtension; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.is; - - @ExtendWith(SpringExtension.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) public class BookControllerIT { - @LocalServerPort - int randomServerPort; + @LocalServerPort int randomServerPort; private TestRestTemplate testRestTemplate; @@ -34,15 +32,15 @@ public void deletingKnownEntityShouldReturn404AfterDeletion() { long bookId = 1; String baseUrl = "http://localhost:" + randomServerPort; - ResponseEntity firstResult = this.testRestTemplate - .getForEntity(baseUrl + "/api/books/" + bookId, JsonNode.class); + ResponseEntity firstResult = + this.testRestTemplate.getForEntity(baseUrl + "/api/books/" + bookId, JsonNode.class); assertThat(firstResult.getStatusCode(), is(HttpStatus.OK)); this.testRestTemplate.delete(baseUrl + "/api/books/" + bookId); - ResponseEntity secondResult = this.testRestTemplate - .getForEntity(baseUrl + "/api/books/" + bookId, JsonNode.class); + ResponseEntity secondResult = + this.testRestTemplate.getForEntity(baseUrl + "/api/books/" + bookId, JsonNode.class); assertThat(secondResult.getStatusCode(), is(HttpStatus.NOT_FOUND)); } diff --git a/demo-crud-application/src/test/java/de/rieckpil/blog/BookControllerTest.java b/demo-crud-application/src/test/java/de/rieckpil/blog/BookControllerTest.java index 2c260087..743b8f52 100644 --- a/demo-crud-application/src/test/java/de/rieckpil/blog/BookControllerTest.java +++ b/demo-crud-application/src/test/java/de/rieckpil/blog/BookControllerTest.java @@ -1,6 +1,15 @@ package de.rieckpil.blog; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.is; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.when; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + import com.fasterxml.jackson.databind.ObjectMapper; +import java.util.List; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.ArgumentCaptor; @@ -12,31 +21,17 @@ import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.test.web.servlet.MockMvc; -import java.util.List; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.hasSize; -import static org.hamcrest.Matchers.is; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.when; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; - @ExtendWith(SpringExtension.class) @WebMvcTest(BookController.class) public class BookControllerTest { - @Autowired - private MockMvc mockMvc; + @Autowired private MockMvc mockMvc; - @Autowired - private ObjectMapper objectMapper; + @Autowired private ObjectMapper objectMapper; - @MockBean - private BookService bookService; + @MockBean private BookService bookService; - @Captor - private ArgumentCaptor bookRequestArgumentCaptor; + @Captor private ArgumentCaptor bookRequestArgumentCaptor; @Test public void postingANewBookShouldCreateANewBook() throws Exception { @@ -49,36 +44,37 @@ public void postingANewBookShouldCreateANewBook() throws Exception { when(bookService.createNewBook(bookRequestArgumentCaptor.capture())).thenReturn(1L); this.mockMvc - .perform(post("/api/books") - .contentType(MediaType.APPLICATION_JSON) - .content(objectMapper.writeValueAsString(bookRequest))) - .andExpect(status().isCreated()) - .andExpect(header().exists("Location")) - .andExpect(header().string("Location", "http://localhost/api/books/1")); + .perform( + post("/api/books") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(bookRequest))) + .andExpect(status().isCreated()) + .andExpect(header().exists("Location")) + .andExpect(header().string("Location", "http://localhost/api/books/1")); assertThat(bookRequestArgumentCaptor.getValue().getAuthor(), is("Duke")); assertThat(bookRequestArgumentCaptor.getValue().getIsbn(), is("1337")); assertThat(bookRequestArgumentCaptor.getValue().getTitle(), is("Java 11")); - } @Test public void allBooksEndpointShouldReturnTwoBooks() throws Exception { - when(bookService.getAllBooks()).thenReturn(List.of( - createBook(1L, "Java 11", "Duke", "1337"), - createBook(2L, "Java EE 8", "Duke", "1338"))); + when(bookService.getAllBooks()) + .thenReturn( + List.of( + createBook(1L, "Java 11", "Duke", "1337"), + createBook(2L, "Java EE 8", "Duke", "1338"))); this.mockMvc - .perform(get("/api/books")) - .andExpect(status().isOk()) - .andExpect(content().contentType("application/json")) - .andExpect(jsonPath("$", hasSize(2))) - .andExpect(jsonPath("$[0].title", is("Java 11"))) - .andExpect(jsonPath("$[0].author", is("Duke"))) - .andExpect(jsonPath("$[0].isbn", is("1337"))) - .andExpect(jsonPath("$[0].id", is(1))); - + .perform(get("/api/books")) + .andExpect(status().isOk()) + .andExpect(content().contentType("application/json")) + .andExpect(jsonPath("$", hasSize(2))) + .andExpect(jsonPath("$[0].title", is("Java 11"))) + .andExpect(jsonPath("$[0].author", is("Duke"))) + .andExpect(jsonPath("$[0].isbn", is("1337"))) + .andExpect(jsonPath("$[0].id", is(1))); } @Test @@ -87,25 +83,22 @@ public void getBookWithIdOneShouldReturnABook() throws Exception { when(bookService.getBookById(1L)).thenReturn(createBook(1L, "Java 11", "Duke", "1337")); this.mockMvc - .perform(get("/api/books/1")) - .andExpect(status().isOk()) - .andExpect(content().contentType("application/json")) - .andExpect(jsonPath("$.title", is("Java 11"))) - .andExpect(jsonPath("$.author", is("Duke"))) - .andExpect(jsonPath("$.isbn", is("1337"))) - .andExpect(jsonPath("$.id", is(1))); - + .perform(get("/api/books/1")) + .andExpect(status().isOk()) + .andExpect(content().contentType("application/json")) + .andExpect(jsonPath("$.title", is("Java 11"))) + .andExpect(jsonPath("$.author", is("Duke"))) + .andExpect(jsonPath("$.isbn", is("1337"))) + .andExpect(jsonPath("$.id", is(1))); } @Test public void getBookWithUnknownIdShouldReturn404() throws Exception { - when(bookService.getBookById(1L)).thenThrow(new BookNotFoundException("Book with id '1' not found")); - - this.mockMvc - .perform(get("/api/books/1")) - .andExpect(status().isNotFound()); + when(bookService.getBookById(1L)) + .thenThrow(new BookNotFoundException("Book with id '1' not found")); + this.mockMvc.perform(get("/api/books/1")).andExpect(status().isNotFound()); } @Test @@ -117,23 +110,23 @@ public void updateBookWithKnownIdShouldUpdateTheBook() throws Exception { bookRequest.setTitle("Java 12"); when(bookService.updateBook(eq(1L), bookRequestArgumentCaptor.capture())) - .thenReturn(createBook(1L, "Java 12", "Duke", "1337")); + .thenReturn(createBook(1L, "Java 12", "Duke", "1337")); this.mockMvc - .perform(put("/api/books/1") - .contentType(MediaType.APPLICATION_JSON) - .content(objectMapper.writeValueAsString(bookRequest))) - .andExpect(status().isOk()) - .andExpect(content().contentType("application/json")) - .andExpect(jsonPath("$.title", is("Java 12"))) - .andExpect(jsonPath("$.author", is("Duke"))) - .andExpect(jsonPath("$.isbn", is("1337"))) - .andExpect(jsonPath("$.id", is(1))); + .perform( + put("/api/books/1") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(bookRequest))) + .andExpect(status().isOk()) + .andExpect(content().contentType("application/json")) + .andExpect(jsonPath("$.title", is("Java 12"))) + .andExpect(jsonPath("$.author", is("Duke"))) + .andExpect(jsonPath("$.isbn", is("1337"))) + .andExpect(jsonPath("$.id", is(1))); assertThat(bookRequestArgumentCaptor.getValue().getAuthor(), is("Duke")); assertThat(bookRequestArgumentCaptor.getValue().getIsbn(), is("1337")); assertThat(bookRequestArgumentCaptor.getValue().getTitle(), is("Java 12")); - } @Test @@ -145,14 +138,14 @@ public void updateBookWithUnknownIdShouldReturn404() throws Exception { bookRequest.setTitle("Java 12"); when(bookService.updateBook(eq(42L), bookRequestArgumentCaptor.capture())) - .thenThrow(new BookNotFoundException("The book with id '42' was not found")); + .thenThrow(new BookNotFoundException("The book with id '42' was not found")); this.mockMvc - .perform(put("/api/books/42") - .contentType(MediaType.APPLICATION_JSON) - .content(objectMapper.writeValueAsString(bookRequest))) - .andExpect(status().isNotFound()); - + .perform( + put("/api/books/42") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(bookRequest))) + .andExpect(status().isNotFound()); } private Book createBook(Long id, String title, String author, String isbn) { @@ -163,5 +156,4 @@ private Book createBook(Long id, String title, String author, String isbn) { book.setId(id); return book; } - } diff --git a/demo-crud-application/src/test/java/de/rieckpil/blog/DemoCrudApplicationTests.java b/demo-crud-application/src/test/java/de/rieckpil/blog/DemoCrudApplicationTests.java index b9916e50..ceaf46ee 100644 --- a/demo-crud-application/src/test/java/de/rieckpil/blog/DemoCrudApplicationTests.java +++ b/demo-crud-application/src/test/java/de/rieckpil/blog/DemoCrudApplicationTests.java @@ -7,7 +7,5 @@ class DemoCrudApplicationTests { @Test - void contextLoads() { - } - + void contextLoads() {} } diff --git a/dependency-version-update-plugin/pom.xml b/dependency-version-update-plugin/pom.xml index 2e97a847..45a30347 100644 --- a/dependency-version-update-plugin/pom.xml +++ b/dependency-version-update-plugin/pom.xml @@ -1,25 +1,19 @@ - + 4.0.0 - org.springframework.boot - spring-boot-starter-parent - 2.2.5.RELEASE - + de.rieckpil.blog + blog-parent + 0.0.1-SNAPSHOT + ../pom.xml - de.rieckpil.blog dependency-version-update-plugin 0.0.1-SNAPSHOT dependency-version-update-plugin Demo project for Spring Boot - - 11 - - org.springframework.boot @@ -36,12 +30,6 @@ 1.3 - - org.testcontainers - testcontainers - 1.12.5 - - com.h2database h2 @@ -51,26 +39,46 @@ org.springframework.boot spring-boot-starter-test test - - - org.junit.vintage - junit-vintage-engine - - + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + + + true + + spring-snapshots + Spring Snapshots + https://repo.spring.io/snapshot + + + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + + + true + + spring-snapshots + Spring Snapshots + https://repo.spring.io/snapshot + + + org.springframework.boot spring-boot-maven-plugin - - org.apache.maven.plugins - maven-compiler-plugin - 3.1 - @@ -94,35 +102,4 @@ - - - spring-milestones - Spring Milestones - https://repo.spring.io/milestone - - - spring-snapshots - Spring Snapshots - https://repo.spring.io/snapshot - - true - - - - - - spring-milestones - Spring Milestones - https://repo.spring.io/milestone - - - spring-snapshots - Spring Snapshots - https://repo.spring.io/snapshot - - true - - - - diff --git a/dependency-version-update-plugin/src/main/java/de/rieckpil/blog/Application.java b/dependency-version-update-plugin/src/main/java/de/rieckpil/blog/Application.java index bd5e4c56..6511f3c1 100644 --- a/dependency-version-update-plugin/src/main/java/de/rieckpil/blog/Application.java +++ b/dependency-version-update-plugin/src/main/java/de/rieckpil/blog/Application.java @@ -9,5 +9,4 @@ public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } - } diff --git a/dependency-version-update-plugin/src/test/java/de/rieckpil/blog/ApplicationTests.java b/dependency-version-update-plugin/src/test/java/de/rieckpil/blog/ApplicationTests.java index 874de1b2..4f1f1cf4 100644 --- a/dependency-version-update-plugin/src/test/java/de/rieckpil/blog/ApplicationTests.java +++ b/dependency-version-update-plugin/src/test/java/de/rieckpil/blog/ApplicationTests.java @@ -7,7 +7,5 @@ class ApplicationTests { @Test - void contextLoads() { - } - + void contextLoads() {} } diff --git a/deploy-spring-boot-to-gke/pom.xml b/deploy-spring-boot-to-gke/pom.xml index cde23383..d0df8ce3 100644 --- a/deploy-spring-boot-to-gke/pom.xml +++ b/deploy-spring-boot-to-gke/pom.xml @@ -2,22 +2,19 @@ 4.0.0 + - org.springframework.boot - spring-boot-starter-parent - 2.3.0.RELEASE - + de.rieckpil.blog + blog-parent + 0.0.1-SNAPSHOT + ../pom.xml - de.rieckpil.blog + deploy-spring-boot-to-gke 0.0.1-SNAPSHOT deploy-spring-boot-to-gke Demo project for Spring Boot - - 11 - - org.springframework.boot diff --git a/deploy-spring-boot-to-gke/src/main/java/de/rieckpil/blog/DeploySpringBootToGkeApplication.java b/deploy-spring-boot-to-gke/src/main/java/de/rieckpil/blog/DeploySpringBootToGkeApplication.java index 4081d887..043b2819 100644 --- a/deploy-spring-boot-to-gke/src/main/java/de/rieckpil/blog/DeploySpringBootToGkeApplication.java +++ b/deploy-spring-boot-to-gke/src/main/java/de/rieckpil/blog/DeploySpringBootToGkeApplication.java @@ -9,5 +9,4 @@ public class DeploySpringBootToGkeApplication { public static void main(String[] args) { SpringApplication.run(DeploySpringBootToGkeApplication.class, args); } - } diff --git a/deploy-spring-boot-to-gke/src/test/java/de/rieckpil/blog/DeploySpringBootToGkeApplicationTests.java b/deploy-spring-boot-to-gke/src/test/java/de/rieckpil/blog/DeploySpringBootToGkeApplicationTests.java index 3d4d9680..ddfc4627 100644 --- a/deploy-spring-boot-to-gke/src/test/java/de/rieckpil/blog/DeploySpringBootToGkeApplicationTests.java +++ b/deploy-spring-boot-to-gke/src/test/java/de/rieckpil/blog/DeploySpringBootToGkeApplicationTests.java @@ -1,16 +1,11 @@ package de.rieckpil.blog; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; -@RunWith(SpringRunner.class) @SpringBootTest public class DeploySpringBootToGkeApplicationTests { @Test - public void contextLoads() { - } - + public void contextLoads() {} } diff --git a/difference-between-mock-and-mockbean/pom.xml b/difference-between-mock-and-mockbean/pom.xml index d64fe6f1..36785778 100644 --- a/difference-between-mock-and-mockbean/pom.xml +++ b/difference-between-mock-and-mockbean/pom.xml @@ -2,22 +2,19 @@ 4.0.0 + - org.springframework.boot - spring-boot-starter-parent - 2.3.5.RELEASE - + de.rieckpil.blog + blog-parent + 0.0.1-SNAPSHOT + ../pom.xml - de.rieckpil.blog + difference-between-mock-and-mockbean 0.0.1-SNAPSHOT difference-between-mock-and-mockbean Demo project for Spring Boot - - 11 - - org.springframework.boot @@ -28,12 +25,6 @@ org.springframework.boot spring-boot-starter-test test - - - org.junit.vintage - junit-vintage-engine - - diff --git a/difference-between-mock-and-mockbean/src/main/java/de/rieckpil/blog/Application.java b/difference-between-mock-and-mockbean/src/main/java/de/rieckpil/blog/Application.java index bd5e4c56..6511f3c1 100644 --- a/difference-between-mock-and-mockbean/src/main/java/de/rieckpil/blog/Application.java +++ b/difference-between-mock-and-mockbean/src/main/java/de/rieckpil/blog/Application.java @@ -9,5 +9,4 @@ public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } - } diff --git a/difference-between-mock-and-mockbean/src/main/java/de/rieckpil/blog/ExpensiveRealtimeStockApiClient.java b/difference-between-mock-and-mockbean/src/main/java/de/rieckpil/blog/ExpensiveRealtimeStockApiClient.java index c6b75b06..4a95e780 100644 --- a/difference-between-mock-and-mockbean/src/main/java/de/rieckpil/blog/ExpensiveRealtimeStockApiClient.java +++ b/difference-between-mock-and-mockbean/src/main/java/de/rieckpil/blog/ExpensiveRealtimeStockApiClient.java @@ -1,10 +1,9 @@ package de.rieckpil.blog; -import org.springframework.stereotype.Component; - -import javax.annotation.PostConstruct; +import jakarta.annotation.PostConstruct; import java.math.BigDecimal; import java.util.concurrent.ThreadLocalRandom; +import org.springframework.stereotype.Component; @Component public class ExpensiveRealtimeStockApiClient { diff --git a/difference-between-mock-and-mockbean/src/main/java/de/rieckpil/blog/StockApiClient.java b/difference-between-mock-and-mockbean/src/main/java/de/rieckpil/blog/StockApiClient.java index 4dc2cd89..b1c41ca4 100644 --- a/difference-between-mock-and-mockbean/src/main/java/de/rieckpil/blog/StockApiClient.java +++ b/difference-between-mock-and-mockbean/src/main/java/de/rieckpil/blog/StockApiClient.java @@ -1,9 +1,8 @@ package de.rieckpil.blog; -import org.springframework.stereotype.Component; - import java.math.BigDecimal; import java.util.concurrent.ThreadLocalRandom; +import org.springframework.stereotype.Component; @Component public class StockApiClient { diff --git a/difference-between-mock-and-mockbean/src/main/java/de/rieckpil/blog/StockController.java b/difference-between-mock-and-mockbean/src/main/java/de/rieckpil/blog/StockController.java index f317c158..221bc623 100644 --- a/difference-between-mock-and-mockbean/src/main/java/de/rieckpil/blog/StockController.java +++ b/difference-between-mock-and-mockbean/src/main/java/de/rieckpil/blog/StockController.java @@ -1,12 +1,11 @@ package de.rieckpil.blog; +import java.math.BigDecimal; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -import java.math.BigDecimal; - @RestController @RequestMapping("/api/stocks") public class StockController { diff --git a/difference-between-mock-and-mockbean/src/main/java/de/rieckpil/blog/StockService.java b/difference-between-mock-and-mockbean/src/main/java/de/rieckpil/blog/StockService.java index 73f46d3a..1794f8e3 100644 --- a/difference-between-mock-and-mockbean/src/main/java/de/rieckpil/blog/StockService.java +++ b/difference-between-mock-and-mockbean/src/main/java/de/rieckpil/blog/StockService.java @@ -1,9 +1,8 @@ package de.rieckpil.blog; -import org.springframework.stereotype.Service; - import java.math.BigDecimal; import java.util.Set; +import org.springframework.stereotype.Service; @Service public class StockService { diff --git a/difference-between-mock-and-mockbean/src/test/java/de/rieckpil/blog/ApplicationTest.java b/difference-between-mock-and-mockbean/src/test/java/de/rieckpil/blog/ApplicationTest.java index 3c46ecaa..c043945a 100644 --- a/difference-between-mock-and-mockbean/src/test/java/de/rieckpil/blog/ApplicationTest.java +++ b/difference-between-mock-and-mockbean/src/test/java/de/rieckpil/blog/ApplicationTest.java @@ -1,20 +1,18 @@ package de.rieckpil.blog; +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment; + import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment; - @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) class ApplicationTest { - @Autowired - private StockApiClient stockApiClient; + @Autowired private StockApiClient stockApiClient; - @MockBean - private ExpensiveRealtimeStockApiClient expensiveRealtimeStockApiClient; + @MockBean private ExpensiveRealtimeStockApiClient expensiveRealtimeStockApiClient; @Test void contextLoadsWithAllBeans() { diff --git a/difference-between-mock-and-mockbean/src/test/java/de/rieckpil/blog/StockControllerTest.java b/difference-between-mock-and-mockbean/src/test/java/de/rieckpil/blog/StockControllerTest.java index 33f6b408..670b5fa0 100644 --- a/difference-between-mock-and-mockbean/src/test/java/de/rieckpil/blog/StockControllerTest.java +++ b/difference-between-mock-and-mockbean/src/test/java/de/rieckpil/blog/StockControllerTest.java @@ -1,33 +1,27 @@ package de.rieckpil.blog; +import static org.mockito.Mockito.when; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import java.math.BigDecimal; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.test.web.servlet.MockMvc; -import java.math.BigDecimal; - -import static org.mockito.Mockito.when; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - @WebMvcTest(StockController.class) class StockControllerTest { - @MockBean - private StockService stockService; + @MockBean private StockService stockService; - @Autowired - private MockMvc mockMvc; + @Autowired private MockMvc mockMvc; @Test void shouldReturnStockPriceFromService() throws Exception { - when(stockService.getLatestPrice("AMZN")) - .thenReturn(BigDecimal.TEN); + when(stockService.getLatestPrice("AMZN")).thenReturn(BigDecimal.TEN); - this.mockMvc - .perform(get("/api/stocks?stockCode=AMZN")) - .andExpect(status().isOk()); + this.mockMvc.perform(get("/api/stocks?stockCode=AMZN")).andExpect(status().isOk()); } } diff --git a/difference-between-mock-and-mockbean/src/test/java/de/rieckpil/blog/StockServiceTest.java b/difference-between-mock-and-mockbean/src/test/java/de/rieckpil/blog/StockServiceTest.java index 5bec15ca..b83a9124 100644 --- a/difference-between-mock-and-mockbean/src/test/java/de/rieckpil/blog/StockServiceTest.java +++ b/difference-between-mock-and-mockbean/src/test/java/de/rieckpil/blog/StockServiceTest.java @@ -1,30 +1,27 @@ package de.rieckpil.blog; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.when; + +import java.math.BigDecimal; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; -import java.math.BigDecimal; - -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.Mockito.when; - @ExtendWith(MockitoExtension.class) class StockServiceTest { - @Mock - private StockApiClient stockApiClient; + @Mock private StockApiClient stockApiClient; - @InjectMocks - private StockService cut; + @InjectMocks private StockService cut; @Test void shouldReturnDefaultPriceWhenClientThrowsException() { when(stockApiClient.getLatestStockPrice("AMZN")) - .thenThrow(new RuntimeException("Remote System Down!")); + .thenThrow(new RuntimeException("Remote System Down!")); BigDecimal result = cut.getLatestPrice("AMZN"); diff --git a/dynamic-sql-querying-with-pagination/.java-version b/dynamic-sql-querying-with-pagination/.java-version deleted file mode 100644 index 2dbc24b3..00000000 --- a/dynamic-sql-querying-with-pagination/.java-version +++ /dev/null @@ -1 +0,0 @@ -11.0 diff --git a/dynamic-sql-querying-with-pagination/pom.xml b/dynamic-sql-querying-with-pagination/pom.xml index b3a89c82..64baf405 100644 --- a/dynamic-sql-querying-with-pagination/pom.xml +++ b/dynamic-sql-querying-with-pagination/pom.xml @@ -1,90 +1,83 @@ - - 4.0.0 - - org.springframework.boot - spring-boot-starter-parent - 2.3.0.RELEASE - - - de.rieckpil.tutorials - dynamic-sql-querying-with-pagination - 0.0.1-SNAPSHOT - jar - dynamic-sql-querying-with-pagination - Quick sample for dynamic SQL querying with pagination + + 4.0.0 - - UTF-8 - UTF-8 - 11 - + + de.rieckpil.blog + blog-parent + 0.0.1-SNAPSHOT + ../pom.xml + - - - org.springframework.boot - spring-boot-starter-data-jpa - - - org.springframework.boot - spring-boot-starter-web - - - com.querydsl - querydsl-jpa - + dynamic-sql-querying-with-pagination + 0.0.1-SNAPSHOT + jar + dynamic-sql-querying-with-pagination + Quick sample for dynamic SQL querying with pagination - - com.h2database - h2 - runtime - - - org.projectlombok - lombok - true - - - org.springframework.boot - spring-boot-starter-test - test - - + + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.springframework.boot + spring-boot-starter-web + + + com.querydsl + querydsl-jpa + - - ${project.artifactId} - - - org.springframework.boot - spring-boot-maven-plugin - - - com.mysema.maven - apt-maven-plugin - 1.1.3 - - - - process - - - target/generated-sources/java - com.querydsl.apt.jpa.JPAAnnotationProcessor - - - - - - com.querydsl - querydsl-apt - ${querydsl.version} - - - - - + + com.h2database + h2 + runtime + + + org.projectlombok + lombok + true + + + org.springframework.boot + spring-boot-starter-test + test + + + + ${project.artifactId} + + + org.springframework.boot + spring-boot-maven-plugin + + + com.mysema.maven + apt-maven-plugin + 1.1.3 + + + com.querydsl + querydsl-apt + ${querydsl.version} + jakarta + + + + + + process + + + target/generated-sources/java + com.querydsl.apt.jpa.JPAAnnotationProcessor + + + + + + diff --git a/dynamic-sql-querying-with-pagination/src/main/java/de/rieckpil/tutorials/DynamicSqlQueryingWithPaginationApplication.java b/dynamic-sql-querying-with-pagination/src/main/java/de/rieckpil/tutorials/DynamicSqlQueryingWithPaginationApplication.java index 35099c11..fcdb4d33 100644 --- a/dynamic-sql-querying-with-pagination/src/main/java/de/rieckpil/tutorials/DynamicSqlQueryingWithPaginationApplication.java +++ b/dynamic-sql-querying-with-pagination/src/main/java/de/rieckpil/tutorials/DynamicSqlQueryingWithPaginationApplication.java @@ -6,7 +6,7 @@ @SpringBootApplication public class DynamicSqlQueryingWithPaginationApplication { - public static void main(String[] args) { - SpringApplication.run(DynamicSqlQueryingWithPaginationApplication.class, args); - } + public static void main(String[] args) { + SpringApplication.run(DynamicSqlQueryingWithPaginationApplication.class, args); + } } diff --git a/dynamic-sql-querying-with-pagination/src/main/java/de/rieckpil/tutorials/Person.java b/dynamic-sql-querying-with-pagination/src/main/java/de/rieckpil/tutorials/Person.java index 1327b7b9..b1be3083 100644 --- a/dynamic-sql-querying-with-pagination/src/main/java/de/rieckpil/tutorials/Person.java +++ b/dynamic-sql-querying-with-pagination/src/main/java/de/rieckpil/tutorials/Person.java @@ -1,30 +1,27 @@ -package de.rieckpil.tutorials; - -import java.time.Instant; - -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; - -import com.querydsl.core.annotations.QueryEntity; - -import lombok.Data; - -@Data -@Entity -@QueryEntity -public class Person { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - private String firstname; - - private String lastname; - - private Instant dob; - - private Integer budget; -} +package de.rieckpil.tutorials; + +import com.querydsl.core.annotations.QueryEntity; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import java.time.Instant; +import lombok.Data; + +@Data +@Entity +@QueryEntity +public class Person { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + private String firstname; + + private String lastname; + + private Instant dob; + + private Integer budget; +} diff --git a/dynamic-sql-querying-with-pagination/src/main/java/de/rieckpil/tutorials/PersonController.java b/dynamic-sql-querying-with-pagination/src/main/java/de/rieckpil/tutorials/PersonController.java index 5f9e8907..7e122b69 100644 --- a/dynamic-sql-querying-with-pagination/src/main/java/de/rieckpil/tutorials/PersonController.java +++ b/dynamic-sql-querying-with-pagination/src/main/java/de/rieckpil/tutorials/PersonController.java @@ -1,7 +1,8 @@ package de.rieckpil.tutorials; +import com.querydsl.core.BooleanBuilder; +import com.querydsl.core.types.Predicate; import java.time.Instant; - import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; @@ -12,55 +13,50 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -import com.querydsl.core.BooleanBuilder; -import com.querydsl.core.types.Predicate; - @RestController @RequestMapping("/persons") public class PersonController { - @Autowired - private PersonRepository personRepository; + @Autowired private PersonRepository personRepository; + + @GetMapping + public Page getPersons( + @RequestParam(name = "page", defaultValue = "0") int page, + @RequestParam(name = "size", defaultValue = "500") int size, + @RequestParam(name = "firstname", required = false) String firstname, + @RequestParam(name = "lastname", required = false) String lastname, + @RequestParam(name = "budget", required = false) Integer budget, + @RequestParam(name = "dobLimit", required = false) Long dobLimit) { - @GetMapping - public Page getPersons( - @RequestParam(name = "page", defaultValue = "0") int page, - @RequestParam(name = "size", defaultValue = "500") int size, - @RequestParam(name = "firstname", required = false) String firstname, - @RequestParam(name = "lastname", required = false) String lastname, - @RequestParam(name = "budget", required = false) Integer budget, - @RequestParam(name = "dobLimit", required = false) Long dobLimit) { + BooleanBuilder booleanBuilder = new BooleanBuilder(); - BooleanBuilder booleanBuilder = new BooleanBuilder(); + if (firstname != null && !firstname.isEmpty()) { + booleanBuilder.and(QPerson.person.firstname.eq(firstname)); + } - if (firstname != null && !firstname.isEmpty()) { - booleanBuilder.and(QPerson.person.firstname.eq(firstname)); - } + if (lastname != null && !lastname.isEmpty()) { + booleanBuilder.and(QPerson.person.lastname.eq(lastname)); + } - if (lastname != null && !lastname.isEmpty()) { - booleanBuilder.and(QPerson.person.lastname.eq(lastname)); - } + if (budget != null && budget != 0) { + booleanBuilder.and(QPerson.person.budget.goe(budget)); + } - if (budget != null && budget != 0) { - booleanBuilder.and(QPerson.person.budget.goe(budget)); - } + if (dobLimit != null && dobLimit != 0) { + booleanBuilder.and(QPerson.person.dob.before(Instant.ofEpochSecond(dobLimit))); + } - if (dobLimit != null && dobLimit != 0) { - booleanBuilder.and( - QPerson.person.dob.before(Instant.ofEpochSecond(dobLimit))); - } + return personRepository.findAll( + booleanBuilder.getValue(), PageRequest.of(page, size, Sort.by(Sort.Direction.ASC, "id"))); + } - return personRepository.findAll(booleanBuilder.getValue(), - PageRequest.of(page, size, Sort.by(Sort.Direction.ASC, "id"))); - } - - @GetMapping("/simplified") - public Page getPersonsSimplified( - @QuerydslPredicate(root = Person.class) Predicate predicate, - @RequestParam(name = "page", defaultValue = "0") int page, - @RequestParam(name = "size", defaultValue = "500") int size) { - - return personRepository.findAll(predicate, PageRequest.of(page, size, Sort.by(Sort.Direction.ASC, "id"))); - } + @GetMapping("/simplified") + public Page getPersonsSimplified( + @QuerydslPredicate(root = Person.class) Predicate predicate, + @RequestParam(name = "page", defaultValue = "0") int page, + @RequestParam(name = "size", defaultValue = "500") int size) { + return personRepository.findAll( + predicate, PageRequest.of(page, size, Sort.by(Sort.Direction.ASC, "id"))); + } } diff --git a/dynamic-sql-querying-with-pagination/src/main/java/de/rieckpil/tutorials/PersonLoader.java b/dynamic-sql-querying-with-pagination/src/main/java/de/rieckpil/tutorials/PersonLoader.java index 66dc7404..21bde891 100644 --- a/dynamic-sql-querying-with-pagination/src/main/java/de/rieckpil/tutorials/PersonLoader.java +++ b/dynamic-sql-querying-with-pagination/src/main/java/de/rieckpil/tutorials/PersonLoader.java @@ -1,42 +1,64 @@ -package de.rieckpil.tutorials; - -import java.time.Instant; -import java.time.LocalDateTime; -import java.time.ZoneOffset; -import java.util.concurrent.ThreadLocalRandom; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.CommandLineRunner; -import org.springframework.stereotype.Service; - -@Service -public class PersonLoader implements CommandLineRunner { - - @Autowired - private PersonRepository personRepository; - - @Override - public void run(String... args) throws Exception { - - System.out.println("Loading entries..."); - - String[] firstnames = { "Tom", "Max", "Anna", "Hanna", "Mike", "Duke", "Fred", "Tim", "Paul", "Luke", "Tobias", - "Timi", "Michelle", "Thomas", "Andrew" }; - String[] lastnames = { "Smith", "Taylor", "Williams", "Hammer", "Lewis", "Jones", "Evans", "Harris", "Mayer", - "Schmid" }; - - LocalDateTime initDate = LocalDateTime.of(1990, 12, 12, 12, 12); - - for (int i = 0; i < 10_000; i++) { - Person p = new Person(); - p.setBudget(ThreadLocalRandom.current().nextInt(10000)); - p.setDob(Instant.ofEpochSecond(initDate.plusDays(i).toEpochSecond(ZoneOffset.UTC))); - p.setFirstname(firstnames[ThreadLocalRandom.current().nextInt(0, firstnames.length)]); - p.setLastname(lastnames[ThreadLocalRandom.current().nextInt(0, lastnames.length)]); - personRepository.save(p); - } - - System.out.println("...Finished loading 10.000 entities"); - } - -} +package de.rieckpil.tutorials; + +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneOffset; +import java.util.concurrent.ThreadLocalRandom; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.stereotype.Service; + +@Service +public class PersonLoader implements CommandLineRunner { + + @Autowired private PersonRepository personRepository; + + @Override + public void run(String... args) throws Exception { + + System.out.println("Loading entries..."); + + String[] firstnames = { + "Tom", + "Max", + "Anna", + "Hanna", + "Mike", + "Duke", + "Fred", + "Tim", + "Paul", + "Luke", + "Tobias", + "Timi", + "Michelle", + "Thomas", + "Andrew" + }; + String[] lastnames = { + "Smith", + "Taylor", + "Williams", + "Hammer", + "Lewis", + "Jones", + "Evans", + "Harris", + "Mayer", + "Schmid" + }; + + LocalDateTime initDate = LocalDateTime.of(1990, 12, 12, 12, 12); + + for (int i = 0; i < 10_000; i++) { + Person p = new Person(); + p.setBudget(ThreadLocalRandom.current().nextInt(10000)); + p.setDob(Instant.ofEpochSecond(initDate.plusDays(i).toEpochSecond(ZoneOffset.UTC))); + p.setFirstname(firstnames[ThreadLocalRandom.current().nextInt(0, firstnames.length)]); + p.setLastname(lastnames[ThreadLocalRandom.current().nextInt(0, lastnames.length)]); + personRepository.save(p); + } + + System.out.println("...Finished loading 10.000 entities"); + } +} diff --git a/dynamic-sql-querying-with-pagination/src/main/java/de/rieckpil/tutorials/PersonRepository.java b/dynamic-sql-querying-with-pagination/src/main/java/de/rieckpil/tutorials/PersonRepository.java index 7380a94b..7c23a790 100644 --- a/dynamic-sql-querying-with-pagination/src/main/java/de/rieckpil/tutorials/PersonRepository.java +++ b/dynamic-sql-querying-with-pagination/src/main/java/de/rieckpil/tutorials/PersonRepository.java @@ -1,8 +1,7 @@ -package de.rieckpil.tutorials; - -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.querydsl.QuerydslPredicateExecutor; - -public interface PersonRepository extends JpaRepository, QuerydslPredicateExecutor { - -} +package de.rieckpil.tutorials; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.querydsl.QuerydslPredicateExecutor; + +public interface PersonRepository + extends JpaRepository, QuerydslPredicateExecutor {} diff --git a/dynamic-sql-querying-with-pagination/src/test/java/de/rieckpil/tutorials/DynamicSqlQueryingWithPaginationApplicationTests.java b/dynamic-sql-querying-with-pagination/src/test/java/de/rieckpil/tutorials/DynamicSqlQueryingWithPaginationApplicationTests.java index dbe64305..4b26aa71 100644 --- a/dynamic-sql-querying-with-pagination/src/test/java/de/rieckpil/tutorials/DynamicSqlQueryingWithPaginationApplicationTests.java +++ b/dynamic-sql-querying-with-pagination/src/test/java/de/rieckpil/tutorials/DynamicSqlQueryingWithPaginationApplicationTests.java @@ -1,16 +1,11 @@ package de.rieckpil.tutorials; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; -@RunWith(SpringRunner.class) @SpringBootTest -public class DynamicSqlQueryingWithPaginationApplicationTests { - - @Test - public void contextLoads() { - } +class DynamicSqlQueryingWithPaginationApplicationTests { + @Test + void contextLoads() {} } diff --git a/expose-git-information-actuator/pom.xml b/expose-git-information-actuator/pom.xml index 9906913d..f6ed2b73 100644 --- a/expose-git-information-actuator/pom.xml +++ b/expose-git-information-actuator/pom.xml @@ -3,7 +3,13 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - de.rieckpil.blog + + de.rieckpil.blog + blog-parent + 0.0.1-SNAPSHOT + ../pom.xml + + expose-git-information-actuator 0.0.1-SNAPSHOT jar @@ -11,19 +17,6 @@ expose-git-information-actuator Codebase for blog post about exposing git information with Actuator - - org.springframework.boot - spring-boot-starter-parent - 2.3.0.RELEASE - - - - - UTF-8 - UTF-8 - 11 - - org.springframework.boot @@ -42,12 +35,6 @@ org.springframework.boot spring-boot-starter-test test - - - org.junit.vintage - junit-vintage-engine - - @@ -66,8 +53,8 @@ - pl.project13.maven - git-commit-id-plugin + io.github.git-commit-id + git-commit-id-maven-plugin diff --git a/expose-git-information-actuator/src/main/resources/application.properties b/expose-git-information-actuator/src/main/resources/application.properties index e69de29b..144f6419 100644 --- a/expose-git-information-actuator/src/main/resources/application.properties +++ b/expose-git-information-actuator/src/main/resources/application.properties @@ -0,0 +1 @@ +management.endpoints.web.exposure.include=health,info diff --git a/expose-git-information-actuator/src/test/java/de/rieckpil/blog/ApplicationTests.java b/expose-git-information-actuator/src/test/java/de/rieckpil/blog/ApplicationTests.java index cfeaf37a..1f57df56 100644 --- a/expose-git-information-actuator/src/test/java/de/rieckpil/blog/ApplicationTests.java +++ b/expose-git-information-actuator/src/test/java/de/rieckpil/blog/ApplicationTests.java @@ -1,29 +1,29 @@ package de.rieckpil.blog; -import org.junit.jupiter.api.Test; +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.web.reactive.server.WebTestClient; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment; - @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) public class ApplicationTests { - @Autowired - private WebTestClient webTestClient; + @Autowired private WebTestClient webTestClient; @Test public void actuatorEndpointContainsGitInformation() { this.webTestClient - .get() - .uri("/actuator/info") - .exchange() - .expectBody() - .jsonPath("$.git.branch").isNotEmpty() - .jsonPath("$.git.commit.id").isNotEmpty() - .jsonPath("$.git.commit.time").isNotEmpty(); + .get() + .uri("/actuator/info") + .exchange() + .expectBody() + .jsonPath("$.git.branch") + .isNotEmpty() + .jsonPath("$.git.commit.id") + .isNotEmpty() + .jsonPath("$.git.commit.time") + .isNotEmpty(); } - } diff --git a/github-actions-java-maven/pom.xml b/github-actions-java-maven/pom.xml index 91f9ab7d..85bca521 100644 --- a/github-actions-java-maven/pom.xml +++ b/github-actions-java-maven/pom.xml @@ -2,23 +2,19 @@ 4.0.0 + - org.springframework.boot - spring-boot-starter-parent - 2.2.2.RELEASE - + de.rieckpil.blog + blog-parent + 0.0.1-SNAPSHOT + ../pom.xml - de.rieckpil.blog + github-actions-java-maven 0.0.1-SNAPSHOT github-actions-java-maven Demo project for Spring Boot - - 11 - 1.16.0 - - org.springframework.boot @@ -42,19 +38,16 @@ org.testcontainers testcontainers - ${testcontainers.version} test org.testcontainers junit-jupiter - ${testcontainers.version} test org.testcontainers postgresql - ${testcontainers.version} test @@ -77,17 +70,6 @@ ${project.artifactId} - - - org.springframework.boot - spring-boot-maven-plugin - - - org.apache.maven.plugins - maven-failsafe-plugin - 3.0.0-M3 - - diff --git a/github-actions-java-maven/src/main/java/de/rieckpil/blog/ApplicationUser.java b/github-actions-java-maven/src/main/java/de/rieckpil/blog/ApplicationUser.java index b00d9291..6a829684 100644 --- a/github-actions-java-maven/src/main/java/de/rieckpil/blog/ApplicationUser.java +++ b/github-actions-java-maven/src/main/java/de/rieckpil/blog/ApplicationUser.java @@ -1,22 +1,19 @@ package de.rieckpil.blog; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; @Entity public class ApplicationUser { - @Id - @GeneratedValue - private Long id; + @Id @GeneratedValue private Long id; @Column(nullable = false, unique = true) private String name; - public ApplicationUser() { - } + public ApplicationUser() {} public ApplicationUser(String name) { this.name = name; diff --git a/github-actions-java-maven/src/main/java/de/rieckpil/blog/ApplicationUserController.java b/github-actions-java-maven/src/main/java/de/rieckpil/blog/ApplicationUserController.java index edde4fbb..7941fae0 100644 --- a/github-actions-java-maven/src/main/java/de/rieckpil/blog/ApplicationUserController.java +++ b/github-actions-java-maven/src/main/java/de/rieckpil/blog/ApplicationUserController.java @@ -1,11 +1,10 @@ package de.rieckpil.blog; +import java.util.List; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import java.util.List; - @RestController @RequestMapping("/api/users") public class ApplicationUserController { diff --git a/github-actions-java-maven/src/main/java/de/rieckpil/blog/ApplicationUserInitializer.java b/github-actions-java-maven/src/main/java/de/rieckpil/blog/ApplicationUserInitializer.java index 1feee4b7..f406c0e5 100644 --- a/github-actions-java-maven/src/main/java/de/rieckpil/blog/ApplicationUserInitializer.java +++ b/github-actions-java-maven/src/main/java/de/rieckpil/blog/ApplicationUserInitializer.java @@ -1,12 +1,11 @@ package de.rieckpil.blog; +import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.CommandLineRunner; import org.springframework.stereotype.Component; -import java.util.List; - @Component public class ApplicationUserInitializer implements CommandLineRunner { @@ -20,11 +19,10 @@ public ApplicationUserInitializer(ApplicationUserRepository applicationUserRepos @Override public void run(String... args) throws Exception { applicationUserRepository.saveAll( - List.of( - new ApplicationUser("duke"), - new ApplicationUser("github"), - new ApplicationUser("actions") - )); + List.of( + new ApplicationUser("duke"), + new ApplicationUser("github"), + new ApplicationUser("actions"))); logger.info("Successfully initialized default application user"); } } diff --git a/github-actions-java-maven/src/main/java/de/rieckpil/blog/ApplicationUserRepository.java b/github-actions-java-maven/src/main/java/de/rieckpil/blog/ApplicationUserRepository.java index 4bbd7251..1ff8b6ad 100644 --- a/github-actions-java-maven/src/main/java/de/rieckpil/blog/ApplicationUserRepository.java +++ b/github-actions-java-maven/src/main/java/de/rieckpil/blog/ApplicationUserRepository.java @@ -2,5 +2,4 @@ import org.springframework.data.jpa.repository.JpaRepository; -public interface ApplicationUserRepository extends JpaRepository { -} +public interface ApplicationUserRepository extends JpaRepository {} diff --git a/github-actions-java-maven/src/test/java/de/rieckpil/blog/GithubActionsJavaMavenApplicationIT.java b/github-actions-java-maven/src/test/java/de/rieckpil/blog/GithubActionsJavaMavenApplicationIT.java index c3452004..cd389d62 100644 --- a/github-actions-java-maven/src/test/java/de/rieckpil/blog/GithubActionsJavaMavenApplicationIT.java +++ b/github-actions-java-maven/src/test/java/de/rieckpil/blog/GithubActionsJavaMavenApplicationIT.java @@ -12,42 +12,41 @@ import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import static org.junit.jupiter.api.Assertions.assertTrue; - @Testcontainers @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @ContextConfiguration(initializers = {GithubActionsJavaMavenApplicationIT.Initializer.class}) class GithubActionsJavaMavenApplicationIT { - @Autowired - private WebTestClient webTestClient; + @Autowired private WebTestClient webTestClient; @Container - private static PostgreSQLContainer postgreSQLContainer = new PostgreSQLContainer() - .withDatabaseName("github") - .withUsername("github") - .withPassword("actions"); + private static PostgreSQLContainer postgreSQLContainer = + new PostgreSQLContainer() + .withDatabaseName("github") + .withUsername("github") + .withPassword("actions"); @Test void shouldReturnThreeDefaultUser() { this.webTestClient - .get() - .uri("/api/users") - .exchange() - .expectStatus() - .isOk() - .expectBody() - .jsonPath("$.length()").isEqualTo(3); + .get() + .uri("/api/users") + .exchange() + .expectStatus() + .isOk() + .expectBody() + .jsonPath("$.length()") + .isEqualTo(3); } static class Initializer - implements ApplicationContextInitializer { + implements ApplicationContextInitializer { public void initialize(ConfigurableApplicationContext configurableApplicationContext) { TestPropertyValues.of( - "spring.datasource.url=" + postgreSQLContainer.getJdbcUrl(), - "spring.datasource.username=" + postgreSQLContainer.getUsername(), - "spring.datasource.password=" + postgreSQLContainer.getPassword() - ).applyTo(configurableApplicationContext.getEnvironment()); + "spring.datasource.url=" + postgreSQLContainer.getJdbcUrl(), + "spring.datasource.username=" + postgreSQLContainer.getUsername(), + "spring.datasource.password=" + postgreSQLContainer.getPassword()) + .applyTo(configurableApplicationContext.getEnvironment()); } } } diff --git a/lazy-loading-of-jpa-attributes-with-hibernate/pom.xml b/lazy-loading-of-jpa-attributes-with-hibernate/pom.xml index bb1bf4de..ed485d66 100644 --- a/lazy-loading-of-jpa-attributes-with-hibernate/pom.xml +++ b/lazy-loading-of-jpa-attributes-with-hibernate/pom.xml @@ -1,9 +1,14 @@ - + 4.0.0 - de.rieckpil.blog + + de.rieckpil.blog + blog-parent + 0.0.1-SNAPSHOT + ../pom.xml + + lazy-loading-of-jpa-attributes-with-hibernate 0.0.1-SNAPSHOT jar @@ -11,19 +16,6 @@ lazy-loading-of-jpa-attributes-with-hibernate Sample project for Lazy Loading of JPA attributes with Hibernate - - org.springframework.boot - spring-boot-starter-parent - 2.3.0.RELEASE - - - - - UTF-8 - UTF-8 - 11 - - org.springframework.boot @@ -57,24 +49,23 @@ org.springframework.boot spring-boot-maven-plugin - - org.hibernate.orm.tooling - hibernate-enhance-maven-plugin - ${hibernate.version} - - - - true - true - - - enhance - - - - + + org.hibernate.orm.tooling + hibernate-enhance-maven-plugin + ${hibernate.version} + + + + enhance + + + true + true + + + + - diff --git a/lazy-loading-of-jpa-attributes-with-hibernate/src/main/java/de/rieckpil/blog/FileUpload.java b/lazy-loading-of-jpa-attributes-with-hibernate/src/main/java/de/rieckpil/blog/FileUpload.java index 71cf1ba9..6e66e62c 100644 --- a/lazy-loading-of-jpa-attributes-with-hibernate/src/main/java/de/rieckpil/blog/FileUpload.java +++ b/lazy-loading-of-jpa-attributes-with-hibernate/src/main/java/de/rieckpil/blog/FileUpload.java @@ -1,11 +1,10 @@ package de.rieckpil.blog; +import jakarta.persistence.*; +import java.time.LocalDateTime; import lombok.Data; import org.hibernate.annotations.CreationTimestamp; -import javax.persistence.*; -import java.time.LocalDateTime; - @Data // Lombok annotation to generate constructor/getter/setter... @Entity public class FileUpload { diff --git a/lazy-loading-of-jpa-attributes-with-hibernate/src/main/java/de/rieckpil/blog/FileUploadRepository.java b/lazy-loading-of-jpa-attributes-with-hibernate/src/main/java/de/rieckpil/blog/FileUploadRepository.java index df4ec19e..f08fde70 100644 --- a/lazy-loading-of-jpa-attributes-with-hibernate/src/main/java/de/rieckpil/blog/FileUploadRepository.java +++ b/lazy-loading-of-jpa-attributes-with-hibernate/src/main/java/de/rieckpil/blog/FileUploadRepository.java @@ -2,5 +2,4 @@ import org.springframework.data.jpa.repository.JpaRepository; -public interface FileUploadRepository extends JpaRepository { -} +public interface FileUploadRepository extends JpaRepository {} diff --git a/lazy-loading-of-jpa-attributes-with-hibernate/src/main/java/de/rieckpil/blog/ReadFileOnStartup.java b/lazy-loading-of-jpa-attributes-with-hibernate/src/main/java/de/rieckpil/blog/ReadFileOnStartup.java index e8bbbcca..ce8500b9 100644 --- a/lazy-loading-of-jpa-attributes-with-hibernate/src/main/java/de/rieckpil/blog/ReadFileOnStartup.java +++ b/lazy-loading-of-jpa-attributes-with-hibernate/src/main/java/de/rieckpil/blog/ReadFileOnStartup.java @@ -1,21 +1,19 @@ package de.rieckpil.blog; +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceContext; +import jakarta.transaction.Transactional; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.CommandLineRunner; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; -import javax.persistence.EntityManager; -import javax.persistence.PersistenceContext; -import javax.transaction.Transactional; - @Component @Order(2) @Slf4j public class ReadFileOnStartup implements CommandLineRunner { - @PersistenceContext - private EntityManager entityManager; + @PersistenceContext private EntityManager entityManager; @Transactional @Override @@ -32,6 +30,5 @@ public void run(String... args) throws Exception { byte[] content = allFileUploads.getFileContent(); log.info("--- the file has: " + content.length + " bytes"); - } } diff --git a/lazy-loading-of-jpa-attributes-with-hibernate/src/main/java/de/rieckpil/blog/StoreFileOnStartup.java b/lazy-loading-of-jpa-attributes-with-hibernate/src/main/java/de/rieckpil/blog/StoreFileOnStartup.java index 9f326d63..46934684 100644 --- a/lazy-loading-of-jpa-attributes-with-hibernate/src/main/java/de/rieckpil/blog/StoreFileOnStartup.java +++ b/lazy-loading-of-jpa-attributes-with-hibernate/src/main/java/de/rieckpil/blog/StoreFileOnStartup.java @@ -1,29 +1,28 @@ package de.rieckpil.blog; +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceContext; +import jakarta.transaction.Transactional; +import java.io.File; +import java.io.FileInputStream; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.CommandLineRunner; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; -import javax.persistence.EntityManager; -import javax.persistence.PersistenceContext; -import javax.transaction.Transactional; -import java.io.File; -import java.io.FileInputStream; - @Component @Order(1) @Slf4j public class StoreFileOnStartup implements CommandLineRunner { - @PersistenceContext - private EntityManager entityManager; + @PersistenceContext private EntityManager entityManager; @Override @Transactional public void run(String... args) throws Exception { - File file = new File(getClass().getClassLoader().getResource("application.properties").getFile()); + File file = + new File(getClass().getClassLoader().getResource("application.properties").getFile()); byte[] fileBytes = new byte[(int) file.length()]; FileInputStream fis = new FileInputStream(file); fis.read(fileBytes); @@ -37,6 +36,5 @@ public void run(String... args) throws Exception { entityManager.flush(); log.info("--- File successfully stored to the database"); - } } diff --git a/lazy-loading-of-jpa-attributes-with-hibernate/src/test/java/de/rieckpil/blog/ApplicationTests.java b/lazy-loading-of-jpa-attributes-with-hibernate/src/test/java/de/rieckpil/blog/ApplicationTests.java index 549ce5df..4f1f1cf4 100644 --- a/lazy-loading-of-jpa-attributes-with-hibernate/src/test/java/de/rieckpil/blog/ApplicationTests.java +++ b/lazy-loading-of-jpa-attributes-with-hibernate/src/test/java/de/rieckpil/blog/ApplicationTests.java @@ -1,16 +1,11 @@ package de.rieckpil.blog; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; -@RunWith(SpringRunner.class) @SpringBootTest -public class ApplicationTests { +class ApplicationTests { @Test - public void contextLoads() { - } - + void contextLoads() {} } diff --git a/load-testing-your-application/pom.xml b/load-testing-your-application/pom.xml index 48b51c96..b5ab19b0 100644 --- a/load-testing-your-application/pom.xml +++ b/load-testing-your-application/pom.xml @@ -2,22 +2,19 @@ 4.0.0 - - org.springframework.boot - spring-boot-starter-parent - 2.3.0.RELEASE - - - de.rieckpil.blog + + + de.rieckpil.blog + blog-parent + 0.0.1-SNAPSHOT + ../pom.xml + + load-testing-your-application 0.0.1-SNAPSHOT load-testing-your-application Load testing your application - - 1.8 - - org.springframework.boot diff --git a/load-testing-your-application/src/main/java/de/rieckpil/blog/LoadTestingYourApplication.java b/load-testing-your-application/src/main/java/de/rieckpil/blog/LoadTestingYourApplication.java index c5dd3b69..888735d9 100644 --- a/load-testing-your-application/src/main/java/de/rieckpil/blog/LoadTestingYourApplication.java +++ b/load-testing-your-application/src/main/java/de/rieckpil/blog/LoadTestingYourApplication.java @@ -1,7 +1,6 @@ package de.rieckpil.blog; import java.util.UUID; - import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; @@ -10,22 +9,19 @@ @SpringBootApplication public class LoadTestingYourApplication implements CommandLineRunner { - @Autowired - private PersonRepository personRepository; - - public static void main(String[] args) { - SpringApplication.run(LoadTestingYourApplication.class, args); - } - - @Override - public void run(String... args) throws Exception { + @Autowired private PersonRepository personRepository; - for (int i = 0; i < 1000; i++) { - this.personRepository.save(new Person(UUID.randomUUID().toString())); - } + public static void main(String[] args) { + SpringApplication.run(LoadTestingYourApplication.class, args); + } - System.out.println("Successfully stored 1.000 database entries"); + @Override + public void run(String... args) throws Exception { - } + for (int i = 0; i < 1000; i++) { + this.personRepository.save(new Person(UUID.randomUUID().toString())); + } + System.out.println("Successfully stored 1.000 database entries"); + } } diff --git a/load-testing-your-application/src/main/java/de/rieckpil/blog/Person.java b/load-testing-your-application/src/main/java/de/rieckpil/blog/Person.java index b2b48865..cf7b1403 100644 --- a/load-testing-your-application/src/main/java/de/rieckpil/blog/Person.java +++ b/load-testing-your-application/src/main/java/de/rieckpil/blog/Person.java @@ -1,40 +1,35 @@ -package de.rieckpil.blog; - -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; - -@Entity -public class Person { - - @Id - @GeneratedValue - private Long id; - - private String name; - - public Person() { - - } - - public Person(String name) { - this.name = name; - } - - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - -} +package de.rieckpil.blog; + +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; + +@Entity +public class Person { + + @Id @GeneratedValue private Long id; + + private String name; + + public Person() {} + + public Person(String name) { + this.name = name; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/load-testing-your-application/src/main/java/de/rieckpil/blog/PersonController.java b/load-testing-your-application/src/main/java/de/rieckpil/blog/PersonController.java index d32ace39..4b14f25e 100644 --- a/load-testing-your-application/src/main/java/de/rieckpil/blog/PersonController.java +++ b/load-testing-your-application/src/main/java/de/rieckpil/blog/PersonController.java @@ -1,24 +1,21 @@ -package de.rieckpil.blog; - -import java.util.concurrent.ThreadLocalRandom; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -@RestController -@RequestMapping("/persons") -public class PersonController { - - @Autowired - private PersonRepository personRepository; - - @GetMapping - public Person getRandomPerson() throws InterruptedException { - long randomLong = ThreadLocalRandom.current().nextLong(1, 1000); - Thread.sleep(randomLong); - return personRepository.findById(randomLong).orElse(new Person("dummy")); - } - -} +package de.rieckpil.blog; + +import java.util.concurrent.ThreadLocalRandom; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/persons") +public class PersonController { + + @Autowired private PersonRepository personRepository; + + @GetMapping + public Person getRandomPerson() throws InterruptedException { + long randomLong = ThreadLocalRandom.current().nextLong(1, 1000); + Thread.sleep(randomLong); + return personRepository.findById(randomLong).orElse(new Person("dummy")); + } +} diff --git a/load-testing-your-application/src/main/java/de/rieckpil/blog/PersonRepository.java b/load-testing-your-application/src/main/java/de/rieckpil/blog/PersonRepository.java index 32494217..6accf5ce 100644 --- a/load-testing-your-application/src/main/java/de/rieckpil/blog/PersonRepository.java +++ b/load-testing-your-application/src/main/java/de/rieckpil/blog/PersonRepository.java @@ -1,7 +1,5 @@ -package de.rieckpil.blog; - -import org.springframework.data.jpa.repository.JpaRepository; - -public interface PersonRepository extends JpaRepository { - -} +package de.rieckpil.blog; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface PersonRepository extends JpaRepository {} diff --git a/load-testing-your-application/src/test/java/de/rieckpil/blog/LoadTestingYourApplicationTests.java b/load-testing-your-application/src/test/java/de/rieckpil/blog/LoadTestingYourApplicationTests.java index e8581f17..72811ad9 100644 --- a/load-testing-your-application/src/test/java/de/rieckpil/blog/LoadTestingYourApplicationTests.java +++ b/load-testing-your-application/src/test/java/de/rieckpil/blog/LoadTestingYourApplicationTests.java @@ -1,16 +1,11 @@ package de.rieckpil.blog; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; -@RunWith(SpringRunner.class) @SpringBootTest -public class LoadTestingYourApplicationTests { - - @Test - public void contextLoads() { - } +class LoadTestingYourApplicationTests { + @Test + void contextLoads() {} } diff --git a/maven-plugins-to-ensure-quality/pom.xml b/maven-plugins-to-ensure-quality/pom.xml index b756d30d..2304c7f5 100644 --- a/maven-plugins-to-ensure-quality/pom.xml +++ b/maven-plugins-to-ensure-quality/pom.xml @@ -4,21 +4,16 @@ 4.0.0 - org.springframework.boot - spring-boot-starter-parent - 2.7.0 - + de.rieckpil.blog + blog-parent + 0.0.1-SNAPSHOT + ../pom.xml - de.rieckpil.blog maven-plugins-to-ensure-quality 0.0.1-SNAPSHOT maven-plugins-to-ensure-quality - - 11 - - org.springframework.boot diff --git a/maven-plugins-to-ensure-quality/src/main/java/de/rieckpil/blog/Application.java b/maven-plugins-to-ensure-quality/src/main/java/de/rieckpil/blog/Application.java index bd5e4c56..6511f3c1 100644 --- a/maven-plugins-to-ensure-quality/src/main/java/de/rieckpil/blog/Application.java +++ b/maven-plugins-to-ensure-quality/src/main/java/de/rieckpil/blog/Application.java @@ -9,5 +9,4 @@ public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } - } diff --git a/maven-plugins-to-ensure-quality/src/main/java/de/rieckpil/blog/BadPracticeFileReader.java b/maven-plugins-to-ensure-quality/src/main/java/de/rieckpil/blog/BadPracticeFileReader.java index be0dcaf8..d6f67a6d 100644 --- a/maven-plugins-to-ensure-quality/src/main/java/de/rieckpil/blog/BadPracticeFileReader.java +++ b/maven-plugins-to-ensure-quality/src/main/java/de/rieckpil/blog/BadPracticeFileReader.java @@ -1,10 +1,9 @@ package de.rieckpil.blog; +import java.io.InputStream; import org.springframework.boot.CommandLineRunner; import org.springframework.stereotype.Component; -import java.io.InputStream; - @Component public class BadPracticeFileReader implements CommandLineRunner { diff --git a/maven-plugins-to-ensure-quality/src/test/java/de/rieckpil/blog/ApplicationTests.java b/maven-plugins-to-ensure-quality/src/test/java/de/rieckpil/blog/ApplicationTests.java index 50e12cfb..4f1f1cf4 100644 --- a/maven-plugins-to-ensure-quality/src/test/java/de/rieckpil/blog/ApplicationTests.java +++ b/maven-plugins-to-ensure-quality/src/test/java/de/rieckpil/blog/ApplicationTests.java @@ -7,6 +7,5 @@ class ApplicationTests { @Test - void contextLoads() { - } + void contextLoads() {} } diff --git a/pom.xml b/pom.xml index cf605f40..b4d944af 100644 --- a/pom.xml +++ b/pom.xml @@ -1,13 +1,13 @@ - + 4.0.0 org.springframework.boot spring-boot-starter-parent 3.2.2 - + + de.rieckpil.blog @@ -15,10 +15,6 @@ 0.0.1-SNAPSHOT pom - - 21 - - spring-boot-datajpatest spring-boot-aws-integration-tests @@ -32,8 +28,59 @@ spring-websocket-integration-tests spring-boot-test-mockmvc-webtestclient-testresttemplate spring-mockmvc-with-webtestclient + load-testing-your-application + whats-new-in-spring-boot-2.1 + whats-new-in-spring-boot-2.2 + whats-new-in-spring-boot-2.3 + avoid-repeating-attributes-in-jpa-entities + lazy-loading-of-jpa-attributes-with-hibernate + send-emails-with-sendgrid-and-spring-boot + demo-crud-application + deploy-spring-boot-to-gke + spring-boot-hibernate-flyway-best-practices + spring-boot-with-kotlin + difference-between-mock-and-mockbean + spring-boot-override-test-properties + spring-boot-test-mail-sending + spring-boot-shedlock + spring-data-mongo-test-testcontainers + dynamic-sql-querying-with-pagination + spring-boot-integration-tests-testcontainers + remote-debugging-spring-boot-application + spring-web-client-demo + spring-boot-uploading-and-downloading-files-with-react + spring-web-client-oauth2-reactive-stack + spring-web-client-oauth2-servlet-stack + spring-web-test-client + spring-web-client-customizing + spring-web-client-testing-with-mockwebserver + spring-web-client-exchange-retrieve + maven-plugins-to-ensure-quality + github-actions-java-maven + spring-web-client-expose-metrics + spring-boot-selenium-integration-tests + testing-json-serialization-spring + spring-web-mvc-cheat-sheet + spring-boot-aws-ssm-parameter-resolving + spring-security-aws-cognito-thymeleaf + testcontainers-reuse-existing-containers + spring-test-context-caching-introduction + spring-boot-kotlin-testcontainers + testing-spring-boot-applications-with-mockmvc + write-concise-web-tests-with-selenide + spring-boot-test-spring-events + spring-boot-testing-tips-and-tricks + expose-git-information-actuator + dependency-version-update-plugin + testing-spring-rest-template + + 21 + UTF-8 + UTF-8 + + @@ -52,10 +99,21 @@ org.springframework.boot spring-boot-maven-plugin + + org.apache.maven.plugins + maven-surefire-plugin + 3.2.5 + org.apache.maven.plugins maven-failsafe-plugin - 3.1.2 + 3.2.5 + + + **/*IT.java + **/*WT.java + + @@ -65,7 +123,61 @@ + + org.apache.maven.plugins + maven-enforcer-plugin + + true + + + + + + + + enforce + + + + + + com.diffplug.spotless + spotless-maven-plugin + 2.43.0 + + + + 1.17.0 + + + + + + + + + + + + check + + validate + + + + + com.github.ekryd.sortpom + sortpom-maven-plugin + 3.3.0 + + + + verify + + validate + + + - diff --git a/remote-debugging-spring-boot-application/pom.xml b/remote-debugging-spring-boot-application/pom.xml index 74270f61..2f09aeaf 100644 --- a/remote-debugging-spring-boot-application/pom.xml +++ b/remote-debugging-spring-boot-application/pom.xml @@ -2,23 +2,19 @@ 4.0.0 + - org.springframework.boot - spring-boot-starter-parent - 2.3.0.RELEASE - + de.rieckpil.blog + blog-parent + 0.0.1-SNAPSHOT + ../pom.xml - de.rieckpil.blog remote-debugging-spring-boot-application 0.0.1-SNAPSHOT remote-debugging-spring-boot-application Demo project for Remote debugging of Spring Boot application - - 11 - - org.springframework.boot @@ -31,7 +27,7 @@ com.github.javafaker javafaker - 0.17.2 + 1.0.2 diff --git a/remote-debugging-spring-boot-application/src/main/java/de/rieckpil/blog/Book.java b/remote-debugging-spring-boot-application/src/main/java/de/rieckpil/blog/Book.java index a760252f..0cd224bd 100644 --- a/remote-debugging-spring-boot-application/src/main/java/de/rieckpil/blog/Book.java +++ b/remote-debugging-spring-boot-application/src/main/java/de/rieckpil/blog/Book.java @@ -1,19 +1,16 @@ package de.rieckpil.blog; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; import lombok.Data; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; - @Data @Entity public class Book { - @Id - @GeneratedValue - private Long id; + @Id @GeneratedValue private Long id; @Column(nullable = false, unique = true) private String isbn; @@ -23,5 +20,4 @@ public class Book { @Column(nullable = false) private String title; - } diff --git a/remote-debugging-spring-boot-application/src/main/java/de/rieckpil/blog/BookController.java b/remote-debugging-spring-boot-application/src/main/java/de/rieckpil/blog/BookController.java index 68d6c485..566248f2 100644 --- a/remote-debugging-spring-boot-application/src/main/java/de/rieckpil/blog/BookController.java +++ b/remote-debugging-spring-boot-application/src/main/java/de/rieckpil/blog/BookController.java @@ -1,5 +1,7 @@ package de.rieckpil.blog; +import java.util.List; +import java.util.Optional; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; @@ -7,16 +9,12 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import java.util.List; -import java.util.Optional; - @Slf4j @RestController @RequestMapping("/api/books") public class BookController { - @Autowired - private BookRepository bookRepository; + @Autowired private BookRepository bookRepository; @GetMapping public List getAllBooks() { diff --git a/remote-debugging-spring-boot-application/src/main/java/de/rieckpil/blog/BookInitializer.java b/remote-debugging-spring-boot-application/src/main/java/de/rieckpil/blog/BookInitializer.java index 6509602c..83f7cb75 100644 --- a/remote-debugging-spring-boot-application/src/main/java/de/rieckpil/blog/BookInitializer.java +++ b/remote-debugging-spring-boot-application/src/main/java/de/rieckpil/blog/BookInitializer.java @@ -1,19 +1,17 @@ package de.rieckpil.blog; import com.github.javafaker.Faker; +import java.util.UUID; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.stereotype.Component; -import java.util.UUID; - @Slf4j @Component public class BookInitializer implements CommandLineRunner { - @Autowired - private BookRepository bookRepository; + @Autowired private BookRepository bookRepository; @Override public void run(String... args) throws Exception { diff --git a/remote-debugging-spring-boot-application/src/main/java/de/rieckpil/blog/BookRepository.java b/remote-debugging-spring-boot-application/src/main/java/de/rieckpil/blog/BookRepository.java index 7ce6e9b7..e6506dcd 100644 --- a/remote-debugging-spring-boot-application/src/main/java/de/rieckpil/blog/BookRepository.java +++ b/remote-debugging-spring-boot-application/src/main/java/de/rieckpil/blog/BookRepository.java @@ -2,5 +2,4 @@ import org.springframework.data.jpa.repository.JpaRepository; -public interface BookRepository extends JpaRepository { -} +public interface BookRepository extends JpaRepository {} diff --git a/remote-debugging-spring-boot-application/src/main/java/de/rieckpil/blog/RemoteDebuggingSpringBootApplication.java b/remote-debugging-spring-boot-application/src/main/java/de/rieckpil/blog/RemoteDebuggingSpringBootApplication.java index 4db2fbef..003e145b 100644 --- a/remote-debugging-spring-boot-application/src/main/java/de/rieckpil/blog/RemoteDebuggingSpringBootApplication.java +++ b/remote-debugging-spring-boot-application/src/main/java/de/rieckpil/blog/RemoteDebuggingSpringBootApplication.java @@ -9,5 +9,4 @@ public class RemoteDebuggingSpringBootApplication { public static void main(String[] args) { SpringApplication.run(RemoteDebuggingSpringBootApplication.class, args); } - } diff --git a/remote-debugging-spring-boot-application/src/test/java/de/rieckpil/blog/RemoteDebuggingSpringBootApplicationTests.java b/remote-debugging-spring-boot-application/src/test/java/de/rieckpil/blog/RemoteDebuggingSpringBootApplicationTests.java index f02e1287..709a1c86 100644 --- a/remote-debugging-spring-boot-application/src/test/java/de/rieckpil/blog/RemoteDebuggingSpringBootApplicationTests.java +++ b/remote-debugging-spring-boot-application/src/test/java/de/rieckpil/blog/RemoteDebuggingSpringBootApplicationTests.java @@ -1,16 +1,11 @@ package de.rieckpil.blog; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; -@RunWith(SpringRunner.class) @SpringBootTest -public class RemoteDebuggingSpringBootApplicationTests { +class RemoteDebuggingSpringBootApplicationTests { @Test - public void contextLoads() { - } - + void contextLoads() {} } diff --git a/send-emails-with-sendgrid-and-spring-boot/pom.xml b/send-emails-with-sendgrid-and-spring-boot/pom.xml index 1889ec09..c030a64e 100644 --- a/send-emails-with-sendgrid-and-spring-boot/pom.xml +++ b/send-emails-with-sendgrid-and-spring-boot/pom.xml @@ -3,7 +3,13 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - de.rieckpil.blog + + de.rieckpil.blog + blog-parent + 0.0.1-SNAPSHOT + ../pom.xml + + send-emails-with-sendgrid-and-spring-boot 0.0.1-SNAPSHOT jar @@ -11,19 +17,6 @@ send-emails-with-sendgrid-and-spring-boot Demo project for Spring Boot with SendGrid - - org.springframework.boot - spring-boot-starter-parent - 2.3.0.RELEASE - - - - - UTF-8 - UTF-8 - 11 - - org.springframework.boot diff --git a/send-emails-with-sendgrid-and-spring-boot/src/main/java/de/rieckpil/blog/sendemailswithsendgridandspringboot/MailController.java b/send-emails-with-sendgrid-and-spring-boot/src/main/java/de/rieckpil/blog/sendemailswithsendgridandspringboot/MailController.java index df70f549..8c3b1b88 100644 --- a/send-emails-with-sendgrid-and-spring-boot/src/main/java/de/rieckpil/blog/sendemailswithsendgridandspringboot/MailController.java +++ b/send-emails-with-sendgrid-and-spring-boot/src/main/java/de/rieckpil/blog/sendemailswithsendgridandspringboot/MailController.java @@ -7,19 +7,17 @@ import com.sendgrid.helpers.mail.Mail; import com.sendgrid.helpers.mail.objects.Content; import com.sendgrid.helpers.mail.objects.Email; +import java.io.IOException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -import java.io.IOException; - @RestController public class MailController { - @Autowired - private SendGrid sendGrid; + @Autowired private SendGrid sendGrid; @Value("${templateId}") private String EMAIL_TEMPLATE_ID; @@ -30,7 +28,8 @@ public String sendEmailWithSendGrid(@RequestParam("msg") String message) { Email from = new Email("yourname@yourhostname.de"); String subject = "Hello World!"; Email to = new Email("yourname@yourhostname.de"); - Content content = new Content("text/html", "I'm replacing the body tag" + message); + Content content = + new Content("text/html", "I'm replacing the body tag" + message); Mail mail = new Mail(from, subject, to, content); diff --git a/send-emails-with-sendgrid-and-spring-boot/src/test/java/de/rieckpil/blog/sendemailswithsendgridandspringboot/SendEmailsWithSendgridAndSpringBootApplicationTests.java b/send-emails-with-sendgrid-and-spring-boot/src/test/java/de/rieckpil/blog/sendemailswithsendgridandspringboot/SendEmailsWithSendgridAndSpringBootApplicationTests.java index 65e78f59..bc5d75eb 100644 --- a/send-emails-with-sendgrid-and-spring-boot/src/test/java/de/rieckpil/blog/sendemailswithsendgridandspringboot/SendEmailsWithSendgridAndSpringBootApplicationTests.java +++ b/send-emails-with-sendgrid-and-spring-boot/src/test/java/de/rieckpil/blog/sendemailswithsendgridandspringboot/SendEmailsWithSendgridAndSpringBootApplicationTests.java @@ -1,16 +1,11 @@ package de.rieckpil.blog.sendemailswithsendgridandspringboot; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; -@RunWith(SpringRunner.class) @SpringBootTest public class SendEmailsWithSendgridAndSpringBootApplicationTests { @Test - public void contextLoads() { - } - + public void contextLoads() {} } diff --git a/spotless.importorder b/spotless.importorder new file mode 100644 index 00000000..17b0cf9d --- /dev/null +++ b/spotless.importorder @@ -0,0 +1,7 @@ +# Organize Import Order +# See https://github.com/diffplug/spotless/issues/522#issuecomment-661921466 +# Last refers to static imports +0=java +1=javax +2= +3=\# diff --git a/spring-boot-aws-integration-tests/pom.xml b/spring-boot-aws-integration-tests/pom.xml index 7c61e4c7..6790a61c 100644 --- a/spring-boot-aws-integration-tests/pom.xml +++ b/spring-boot-aws-integration-tests/pom.xml @@ -1,6 +1,5 @@ - + 4.0.0 @@ -19,6 +18,18 @@ 3.1.0 + + + + io.awspring.cloud + spring-cloud-aws-dependencies + ${awspring.version} + pom + import + + + + org.springframework.boot @@ -50,18 +61,6 @@ - - - - io.awspring.cloud - spring-cloud-aws-dependencies - ${awspring.version} - pom - import - - - - diff --git a/spring-boot-aws-integration-tests/src/main/java/de/rieckpil/blog/Application.java b/spring-boot-aws-integration-tests/src/main/java/de/rieckpil/blog/Application.java index bd5e4c56..6511f3c1 100644 --- a/spring-boot-aws-integration-tests/src/main/java/de/rieckpil/blog/Application.java +++ b/spring-boot-aws-integration-tests/src/main/java/de/rieckpil/blog/Application.java @@ -9,5 +9,4 @@ public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } - } diff --git a/spring-boot-aws-integration-tests/src/main/java/de/rieckpil/blog/MessagingConfig.java b/spring-boot-aws-integration-tests/src/main/java/de/rieckpil/blog/MessagingConfig.java index 9a71617a..38dcf648 100644 --- a/spring-boot-aws-integration-tests/src/main/java/de/rieckpil/blog/MessagingConfig.java +++ b/spring-boot-aws-integration-tests/src/main/java/de/rieckpil/blog/MessagingConfig.java @@ -9,10 +9,11 @@ public class MessagingConfig { @Bean - public MappingJackson2MessageConverter mappingJackson2MessageConverter(ObjectMapper objectMapper) { - MappingJackson2MessageConverter jackson2MessageConverter = new MappingJackson2MessageConverter(); + public MappingJackson2MessageConverter mappingJackson2MessageConverter( + ObjectMapper objectMapper) { + MappingJackson2MessageConverter jackson2MessageConverter = + new MappingJackson2MessageConverter(); jackson2MessageConverter.setObjectMapper(objectMapper); return jackson2MessageConverter; } - } diff --git a/spring-boot-aws-integration-tests/src/main/java/de/rieckpil/blog/OrderEvent.java b/spring-boot-aws-integration-tests/src/main/java/de/rieckpil/blog/OrderEvent.java index ab43b0c8..c131c02f 100644 --- a/spring-boot-aws-integration-tests/src/main/java/de/rieckpil/blog/OrderEvent.java +++ b/spring-boot-aws-integration-tests/src/main/java/de/rieckpil/blog/OrderEvent.java @@ -1,12 +1,11 @@ package de.rieckpil.blog; +import static com.fasterxml.jackson.annotation.JsonFormat.Shape; + import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonFormat; - import java.time.LocalDateTime; -import static com.fasterxml.jackson.annotation.JsonFormat.Shape; - public class OrderEvent { private String id; @@ -17,12 +16,11 @@ public class OrderEvent { @JsonFormat(shape = Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss") private LocalDateTime orderedAt; - public OrderEvent() { - - } + public OrderEvent() {} @JsonCreator - public OrderEvent(String id, String product, String message, LocalDateTime orderedAt, boolean expressDelivery) { + public OrderEvent( + String id, String product, String message, LocalDateTime orderedAt, boolean expressDelivery) { this.id = id; this.product = product; this.message = message; @@ -72,12 +70,20 @@ public void setExpressDelivery(boolean expressDelivery) { @Override public String toString() { - return "OrderEvent{" + - "id='" + id + '\'' + - ", product='" + product + '\'' + - ", message='" + message + '\'' + - ", orderedAt=" + orderedAt + - ", expressDelivery=" + expressDelivery + - '}'; + return "OrderEvent{" + + "id='" + + id + + '\'' + + ", product='" + + product + + '\'' + + ", message='" + + message + + '\'' + + ", orderedAt=" + + orderedAt + + ", expressDelivery=" + + expressDelivery + + '}'; } } diff --git a/spring-boot-aws-integration-tests/src/main/java/de/rieckpil/blog/SimpleMessageListener.java b/spring-boot-aws-integration-tests/src/main/java/de/rieckpil/blog/SimpleMessageListener.java index 7a4c1f49..90aff904 100644 --- a/spring-boot-aws-integration-tests/src/main/java/de/rieckpil/blog/SimpleMessageListener.java +++ b/spring-boot-aws-integration-tests/src/main/java/de/rieckpil/blog/SimpleMessageListener.java @@ -22,9 +22,9 @@ public class SimpleMessageListener { private final String orderEventBucket; public SimpleMessageListener( - @Value("${event-processing.order-event-bucket}") String orderEventBucket, - S3Client amazonS3, - ObjectMapper objectMapper) { + @Value("${event-processing.order-event-bucket}") String orderEventBucket, + S3Client amazonS3, + ObjectMapper objectMapper) { this.amazonS3 = amazonS3; this.objectMapper = objectMapper; this.orderEventBucket = orderEventBucket; @@ -34,7 +34,9 @@ public SimpleMessageListener( public void processMessage(@Payload OrderEvent orderEvent) throws JsonProcessingException { LOG.info("Incoming order: '{}'", orderEvent); - amazonS3.putObject(PutObjectRequest.builder().bucket(orderEventBucket).key(orderEvent.getId()).build(), RequestBody.fromBytes(objectMapper.writeValueAsString(orderEvent).getBytes())); + amazonS3.putObject( + PutObjectRequest.builder().bucket(orderEventBucket).key(orderEvent.getId()).build(), + RequestBody.fromBytes(objectMapper.writeValueAsString(orderEvent).getBytes())); LOG.info("Successfully uploaded order to S3"); } } diff --git a/spring-boot-aws-integration-tests/src/test/java/de/rieckpil/blog/SimpleMessageListenerIT.java b/spring-boot-aws-integration-tests/src/test/java/de/rieckpil/blog/SimpleMessageListenerIT.java index 8e53767f..293cbe14 100644 --- a/spring-boot-aws-integration-tests/src/test/java/de/rieckpil/blog/SimpleMessageListenerIT.java +++ b/spring-boot-aws-integration-tests/src/test/java/de/rieckpil/blog/SimpleMessageListenerIT.java @@ -1,7 +1,14 @@ package de.rieckpil.blog; -import io.awspring.cloud.s3.S3Exception; +import static java.util.concurrent.TimeUnit.SECONDS; +import static org.awaitility.Awaitility.given; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.testcontainers.containers.localstack.LocalStackContainer.Service.S3; +import static org.testcontainers.containers.localstack.LocalStackContainer.Service.SQS; + import io.awspring.cloud.sqs.operations.SqsTemplate; +import java.io.IOException; +import java.time.LocalDateTime; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -17,15 +24,6 @@ import software.amazon.awssdk.services.s3.model.GetObjectRequest; import software.amazon.awssdk.services.s3.model.NoSuchKeyException; -import java.io.IOException; -import java.time.LocalDateTime; - -import static java.util.concurrent.TimeUnit.SECONDS; -import static org.awaitility.Awaitility.given; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.testcontainers.containers.localstack.LocalStackContainer.Service.S3; -import static org.testcontainers.containers.localstack.LocalStackContainer.Service.SQS; - @Testcontainers @SpringBootTest class SimpleMessageListenerIT { @@ -35,8 +33,8 @@ class SimpleMessageListenerIT { @Container static LocalStackContainer localStack = - new LocalStackContainer(DockerImageName.parse("localstack/localstack:0.13.0")) - .withServices(S3, SQS); + new LocalStackContainer(DockerImageName.parse("localstack/localstack:0.13.0")) + .withServices(S3, SQS); @BeforeAll static void beforeAll() throws IOException, InterruptedException { @@ -54,21 +52,31 @@ static void overrideConfiguration(DynamicPropertyRegistry registry) { registry.add("spring.cloud.aws.credentials.secret-key", localStack::getSecretKey); } - @Autowired - private S3Client amazonS3; + @Autowired private S3Client amazonS3; - @Autowired - private SqsTemplate sqsTemplate; + @Autowired private SqsTemplate sqsTemplate; @Test void messageShouldBeUploadedToBucketOnceConsumedFromQueue() { - sqsTemplate.send(QUEUE_NAME, new GenericMessage<>(new OrderEvent("42", "MacBook Pro", "Please delivery ASAP", LocalDateTime.now().plusDays(4), false))); + sqsTemplate.send( + QUEUE_NAME, + new GenericMessage<>( + new OrderEvent( + "42", + "MacBook Pro", + "Please delivery ASAP", + LocalDateTime.now().plusDays(4), + false))); given() - .ignoreException(NoSuchKeyException.class) - .await() - .atMost(5, SECONDS) - .untilAsserted(() -> assertNotNull(amazonS3.getObject(GetObjectRequest.builder().bucket(BUCKET_NAME).key("42").build()))); + .ignoreException(NoSuchKeyException.class) + .await() + .atMost(5, SECONDS) + .untilAsserted( + () -> + assertNotNull( + amazonS3.getObject( + GetObjectRequest.builder().bucket(BUCKET_NAME).key("42").build()))); } } diff --git a/spring-boot-aws-integration-tests/src/test/java/de/rieckpil/blog/SimpleMessageListenerPre23IT.java b/spring-boot-aws-integration-tests/src/test/java/de/rieckpil/blog/SimpleMessageListenerPre23IT.java index 92571b5c..e13ef5b5 100644 --- a/spring-boot-aws-integration-tests/src/test/java/de/rieckpil/blog/SimpleMessageListenerPre23IT.java +++ b/spring-boot-aws-integration-tests/src/test/java/de/rieckpil/blog/SimpleMessageListenerPre23IT.java @@ -1,7 +1,15 @@ package de.rieckpil.blog; +import static java.util.concurrent.TimeUnit.SECONDS; +import static org.awaitility.Awaitility.given; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.testcontainers.containers.localstack.LocalStackContainer.Service.S3; +import static org.testcontainers.containers.localstack.LocalStackContainer.Service.SQS; + import io.awspring.cloud.s3.S3Exception; import io.awspring.cloud.sqs.operations.SqsTemplate; +import java.io.IOException; +import java.util.Map; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; @@ -22,15 +30,6 @@ import software.amazon.awssdk.services.s3.model.GetObjectRequest; import software.amazon.awssdk.services.sqs.SqsClient; -import java.io.IOException; -import java.util.Map; - -import static java.util.concurrent.TimeUnit.SECONDS; -import static org.awaitility.Awaitility.given; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.testcontainers.containers.localstack.LocalStackContainer.Service.S3; -import static org.testcontainers.containers.localstack.LocalStackContainer.Service.SQS; - @Testcontainers @SpringBootTest @Disabled @@ -41,8 +40,8 @@ class SimpleMessageListenerPre23IT { @Container static LocalStackContainer localStack = - new LocalStackContainer(DockerImageName.parse("localstack/localstack:0.13.0")) - .withServices(S3, SQS); + new LocalStackContainer(DockerImageName.parse("localstack/localstack:0.13.0")) + .withServices(S3, SQS); @BeforeAll static void beforeAll() throws IOException, InterruptedException { @@ -67,30 +66,35 @@ static class AwsTestConfig { @Bean public S3Client amazonS3() { return S3Client.builder() - .credentialsProvider(StaticCredentialsProvider.create(AwsBasicCredentials.create(localStack.getAccessKey(), localStack.getSecretKey()))) - .endpointOverride(localStack.getEndpointOverride(S3)) - .build(); + .credentialsProvider( + StaticCredentialsProvider.create( + AwsBasicCredentials.create(localStack.getAccessKey(), localStack.getSecretKey()))) + .endpointOverride(localStack.getEndpointOverride(S3)) + .build(); } @Bean public SqsClient amazonSQS() { return SqsClient.builder() - .credentialsProvider(StaticCredentialsProvider.create(AwsBasicCredentials.create(localStack.getAccessKey(), localStack.getSecretKey()))) - .endpointOverride(localStack.getEndpointOverride(SQS)) - .build(); + .credentialsProvider( + StaticCredentialsProvider.create( + AwsBasicCredentials.create(localStack.getAccessKey(), localStack.getSecretKey()))) + .endpointOverride(localStack.getEndpointOverride(SQS)) + .build(); } } - @Autowired - private S3Client amazonS3; + @Autowired private S3Client amazonS3; - @Autowired - private SqsTemplate queueMessagingTemplate; + @Autowired private SqsTemplate queueMessagingTemplate; @Test void messageShouldBeUploadedToBucketOnceConsumedFromQueue() { - queueMessagingTemplate.send(QUEUE_NAME, new GenericMessage<>(""" + queueMessagingTemplate.send( + QUEUE_NAME, + new GenericMessage<>( + """ { "id": "13", "message": "Please delivery ASAP", @@ -98,12 +102,17 @@ void messageShouldBeUploadedToBucketOnceConsumedFromQueue() { "orderedAt": "2021-11-11 12:00:00", "expressDelivery": true } - """, Map.of("contentType", "application/json"))); + """, + Map.of("contentType", "application/json"))); given() - .ignoreException(S3Exception.class) - .await() - .atMost(5, SECONDS) - .untilAsserted(() -> assertNotNull(amazonS3.getObject(GetObjectRequest.builder().bucket(BUCKET_NAME).key("13").build()))); + .ignoreException(S3Exception.class) + .await() + .atMost(5, SECONDS) + .untilAsserted( + () -> + assertNotNull( + amazonS3.getObject( + GetObjectRequest.builder().bucket(BUCKET_NAME).key("13").build()))); } } diff --git a/spring-boot-aws-ssm-parameter-resolving/pom.xml b/spring-boot-aws-ssm-parameter-resolving/pom.xml index e0f94493..1ce3040b 100644 --- a/spring-boot-aws-ssm-parameter-resolving/pom.xml +++ b/spring-boot-aws-ssm-parameter-resolving/pom.xml @@ -1,14 +1,14 @@ - + 4.0.0 + - org.springframework.boot - spring-boot-starter-parent - 2.2.6.RELEASE - + de.rieckpil.blog + blog-parent + 0.0.1-SNAPSHOT + ../pom.xml - de.rieckpil.blog + spring-boot-aws-ssm-parameter-resolving 0.0.1-SNAPSHOT spring-boot-aws-ssm-parameter-resolving @@ -19,6 +19,18 @@ Hoxton.SR3 + + + + org.springframework.cloud + spring-cloud-dependencies + ${spring-cloud.version} + pom + import + + + + org.springframework.boot @@ -46,18 +58,6 @@ - - - - org.springframework.cloud - spring-cloud-dependencies - ${spring-cloud.version} - pom - import - - - - diff --git a/spring-boot-aws-ssm-parameter-resolving/src/main/java/de/rieckpil/blog/SpringBootAwsSsmParameterResolvingApplication.java b/spring-boot-aws-ssm-parameter-resolving/src/main/java/de/rieckpil/blog/SpringBootAwsSsmParameterResolvingApplication.java index 556e38bc..adf0f588 100644 --- a/spring-boot-aws-ssm-parameter-resolving/src/main/java/de/rieckpil/blog/SpringBootAwsSsmParameterResolvingApplication.java +++ b/spring-boot-aws-ssm-parameter-resolving/src/main/java/de/rieckpil/blog/SpringBootAwsSsmParameterResolvingApplication.java @@ -9,5 +9,4 @@ public class SpringBootAwsSsmParameterResolvingApplication { public static void main(String[] args) { SpringApplication.run(SpringBootAwsSsmParameterResolvingApplication.class, args); } - } diff --git a/spring-boot-datajpatest/pom.xml b/spring-boot-datajpatest/pom.xml index c4779933..8a2d2236 100644 --- a/spring-boot-datajpatest/pom.xml +++ b/spring-boot-datajpatest/pom.xml @@ -2,6 +2,7 @@ 4.0.0 + de.rieckpil.blog blog-parent diff --git a/spring-boot-datajpatest/src/main/java/de/rieckpil/blog/Application.java b/spring-boot-datajpatest/src/main/java/de/rieckpil/blog/Application.java index bd5e4c56..6511f3c1 100644 --- a/spring-boot-datajpatest/src/main/java/de/rieckpil/blog/Application.java +++ b/spring-boot-datajpatest/src/main/java/de/rieckpil/blog/Application.java @@ -9,5 +9,4 @@ public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } - } diff --git a/spring-boot-datajpatest/src/main/java/de/rieckpil/blog/Order.java b/spring-boot-datajpatest/src/main/java/de/rieckpil/blog/Order.java index ecd3b38e..70627121 100644 --- a/spring-boot-datajpatest/src/main/java/de/rieckpil/blog/Order.java +++ b/spring-boot-datajpatest/src/main/java/de/rieckpil/blog/Order.java @@ -1,8 +1,7 @@ package de.rieckpil.blog; -import org.hibernate.annotations.JdbcTypeCode; - import jakarta.persistence.*; +import org.hibernate.annotations.JdbcTypeCode; import org.hibernate.type.SqlTypes; @Entity @@ -22,8 +21,7 @@ public class Order { @Column(columnDefinition = "jsonb") private String items; - public Order() { - } + public Order() {} public Long getId() { return id; @@ -51,10 +49,15 @@ public void setItems(String info) { @Override public String toString() { - return "Order{" + - "id=" + id + - ", trackingNumber='" + trackingNumber + '\'' + - ", items='" + items + '\'' + - '}'; + return "Order{" + + "id=" + + id + + ", trackingNumber='" + + trackingNumber + + '\'' + + ", items='" + + items + + '\'' + + '}'; } } diff --git a/spring-boot-datajpatest/src/main/java/de/rieckpil/blog/OrderController.java b/spring-boot-datajpatest/src/main/java/de/rieckpil/blog/OrderController.java index 5ce373c3..b0d40a10 100644 --- a/spring-boot-datajpatest/src/main/java/de/rieckpil/blog/OrderController.java +++ b/spring-boot-datajpatest/src/main/java/de/rieckpil/blog/OrderController.java @@ -1,11 +1,10 @@ package de.rieckpil.blog; +import java.util.List; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import java.util.List; - @RestController @RequestMapping("/api/orders") public class OrderController { diff --git a/spring-boot-datajpatest/src/main/java/de/rieckpil/blog/OrderRepository.java b/spring-boot-datajpatest/src/main/java/de/rieckpil/blog/OrderRepository.java index 15682798..98d0cfce 100644 --- a/spring-boot-datajpatest/src/main/java/de/rieckpil/blog/OrderRepository.java +++ b/spring-boot-datajpatest/src/main/java/de/rieckpil/blog/OrderRepository.java @@ -1,17 +1,19 @@ package de.rieckpil.blog; +import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; -import java.util.List; - public interface OrderRepository extends JpaRepository { - @Query(value = """ + @Query( + value = + """ SELECT * FROM orders WHERE items @> '[{"name": "MacBook Pro"}]'; - """, nativeQuery = true) + """, + nativeQuery = true) List findAllContainingMacBookPro(); List findAllByTrackingNumber(String trackingNumber); diff --git a/spring-boot-datajpatest/src/test/java/de/rieckpil/blog/OrderRepositoryInitTest.java b/spring-boot-datajpatest/src/test/java/de/rieckpil/blog/OrderRepositoryInitTest.java index d3607f96..da1cefb9 100644 --- a/spring-boot-datajpatest/src/test/java/de/rieckpil/blog/OrderRepositoryInitTest.java +++ b/spring-boot-datajpatest/src/test/java/de/rieckpil/blog/OrderRepositoryInitTest.java @@ -1,30 +1,35 @@ package de.rieckpil.blog; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.List; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; -import java.util.List; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -@DataJpaTest(properties = { - "spring.test.database.replace=NONE", - "spring.datasource.url=jdbc:tc:postgresql:12:///springboot" -}) +@DataJpaTest( + properties = { + "spring.test.database.replace=NONE", + "spring.datasource.url=jdbc:tc:postgresql:12:///springboot" + }) class OrderRepositoryInitTest { - @Autowired - private OrderRepository orderRepository; + @Autowired private OrderRepository orderRepository; @BeforeEach void initData() { - orderRepository.save(createOrder("42", """ + orderRepository.save( + createOrder( + "42", + """ [{"name": "MacBook Pro", "amount" : 42}, {"name": "iPhone Pro", "amount" : 42}] """)); - orderRepository.save(createOrder("43", """ + orderRepository.save( + createOrder( + "43", + """ [{"name": "Kindle", "amount" : 13}, {"name": "MacBook Pro", "amount" : 10}] """)); diff --git a/spring-boot-datajpatest/src/test/java/de/rieckpil/blog/OrderRepositoryShortTest.java b/spring-boot-datajpatest/src/test/java/de/rieckpil/blog/OrderRepositoryShortTest.java index a097ee8a..16ea9f1a 100644 --- a/spring-boot-datajpatest/src/test/java/de/rieckpil/blog/OrderRepositoryShortTest.java +++ b/spring-boot-datajpatest/src/test/java/de/rieckpil/blog/OrderRepositoryShortTest.java @@ -1,22 +1,21 @@ package de.rieckpil.blog; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.List; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; import org.springframework.test.context.jdbc.Sql; -import java.util.List; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -@DataJpaTest(properties = { - "spring.test.database.replace=NONE", - "spring.datasource.url=jdbc:tc:postgresql:12:///springboot" -}) +@DataJpaTest( + properties = { + "spring.test.database.replace=NONE", + "spring.datasource.url=jdbc:tc:postgresql:12:///springboot" + }) class OrderRepositoryShortTest { - @Autowired - private OrderRepository orderRepository; + @Autowired private OrderRepository orderRepository; @Test @Sql("/scripts/INIT_THREE_ORDERS.sql") diff --git a/spring-boot-datajpatest/src/test/java/de/rieckpil/blog/OrderRepositoryTest.java b/spring-boot-datajpatest/src/test/java/de/rieckpil/blog/OrderRepositoryTest.java index 53285d19..f368342b 100644 --- a/spring-boot-datajpatest/src/test/java/de/rieckpil/blog/OrderRepositoryTest.java +++ b/spring-boot-datajpatest/src/test/java/de/rieckpil/blog/OrderRepositoryTest.java @@ -1,5 +1,8 @@ package de.rieckpil.blog; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.List; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; @@ -10,20 +13,17 @@ import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.util.List; - -import static org.junit.jupiter.api.Assertions.assertEquals; - @DataJpaTest @Testcontainers @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) class OrderRepositoryTest { @Container - static PostgreSQLContainer database = new PostgreSQLContainer("postgres:12") - .withDatabaseName("springboot") - .withPassword("springboot") - .withUsername("springboot"); + static PostgreSQLContainer database = + new PostgreSQLContainer("postgres:12") + .withDatabaseName("springboot") + .withPassword("springboot") + .withUsername("springboot"); @DynamicPropertySource static void setDatasourceProperties(DynamicPropertyRegistry propertyRegistry) { @@ -32,17 +32,22 @@ static void setDatasourceProperties(DynamicPropertyRegistry propertyRegistry) { propertyRegistry.add("spring.datasource.username", database::getUsername); } - @Autowired - private OrderRepository orderRepository; + @Autowired private OrderRepository orderRepository; @Test void shouldReturnOrdersThatContainMacBookPro() { - orderRepository.save(createOrder("42", """ + orderRepository.save( + createOrder( + "42", + """ [{"name": "MacBook Pro", "amount" : 42}, {"name": "iPhone Pro", "amount" : 42}] """)); - orderRepository.save(createOrder("43", """ + orderRepository.save( + createOrder( + "43", + """ [{"name": "Kindle", "amount" : 13}, {"name": "MacBook Pro", "amount" : 10}] """)); diff --git a/spring-boot-feature-toggles-with-togglz/src/main/java/de/rieckpil/blog/Application.java b/spring-boot-feature-toggles-with-togglz/src/main/java/de/rieckpil/blog/Application.java index bd5e4c56..6511f3c1 100644 --- a/spring-boot-feature-toggles-with-togglz/src/main/java/de/rieckpil/blog/Application.java +++ b/spring-boot-feature-toggles-with-togglz/src/main/java/de/rieckpil/blog/Application.java @@ -9,5 +9,4 @@ public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } - } diff --git a/spring-boot-feature-toggles-with-togglz/src/main/java/de/rieckpil/blog/BookController.java b/spring-boot-feature-toggles-with-togglz/src/main/java/de/rieckpil/blog/BookController.java index b5495696..d4fc18b4 100644 --- a/spring-boot-feature-toggles-with-togglz/src/main/java/de/rieckpil/blog/BookController.java +++ b/spring-boot-feature-toggles-with-togglz/src/main/java/de/rieckpil/blog/BookController.java @@ -4,6 +4,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; +import java.time.LocalDate; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; @@ -11,8 +12,6 @@ import org.togglz.core.manager.FeatureManager; import org.togglz.core.util.NamedFeature; -import java.time.LocalDate; - @RestController @RequestMapping("/books") public class BookController { diff --git a/spring-boot-feature-toggles-with-togglz/src/main/java/de/rieckpil/blog/BookstoreFeatures.java b/spring-boot-feature-toggles-with-togglz/src/main/java/de/rieckpil/blog/BookstoreFeatures.java index ddd8f73b..bbe70a53 100644 --- a/spring-boot-feature-toggles-with-togglz/src/main/java/de/rieckpil/blog/BookstoreFeatures.java +++ b/spring-boot-feature-toggles-with-togglz/src/main/java/de/rieckpil/blog/BookstoreFeatures.java @@ -5,7 +5,6 @@ import org.togglz.core.annotation.Label; public enum BookstoreFeatures implements Feature { - @EnabledByDefault @Label("Provide extended information about a book") EXTENDED_INFORMATION, diff --git a/spring-boot-feature-toggles-with-togglz/src/test/java/de/rieckpil/blog/ApplicationTest.java b/spring-boot-feature-toggles-with-togglz/src/test/java/de/rieckpil/blog/ApplicationTest.java index b99a33cd..b6751e0d 100644 --- a/spring-boot-feature-toggles-with-togglz/src/test/java/de/rieckpil/blog/ApplicationTest.java +++ b/spring-boot-feature-toggles-with-togglz/src/test/java/de/rieckpil/blog/ApplicationTest.java @@ -7,6 +7,5 @@ class ApplicationTest { @Test - void contextLoads() { - } + void contextLoads() {} } diff --git a/spring-boot-hibernate-flyway-best-practices/pom.xml b/spring-boot-hibernate-flyway-best-practices/pom.xml index 52a491e5..83434e51 100644 --- a/spring-boot-hibernate-flyway-best-practices/pom.xml +++ b/spring-boot-hibernate-flyway-best-practices/pom.xml @@ -3,23 +3,19 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - - org.springframework.boot - spring-boot-starter-parent - 2.3.0.RELEASE - - - de.rieckpil.blog + + de.rieckpil.blog + blog-parent + 0.0.1-SNAPSHOT + ../pom.xml + + spring-boot-hibernate-flyway-best-practices 0.0.1-SNAPSHOT spring-boot-hibernate-flyway-best-practices Best practices using Flyway with Hibernate - - 11 - - org.springframework.boot @@ -65,5 +61,4 @@ - diff --git a/spring-boot-hibernate-flyway-best-practices/src/main/java/db/migration/V004__UPDATE_REVIEWS.java b/spring-boot-hibernate-flyway-best-practices/src/main/java/db/migration/V004__UPDATE_REVIEWS.java index 5a46ffc3..346a85b8 100644 --- a/spring-boot-hibernate-flyway-best-practices/src/main/java/db/migration/V004__UPDATE_REVIEWS.java +++ b/spring-boot-hibernate-flyway-best-practices/src/main/java/db/migration/V004__UPDATE_REVIEWS.java @@ -1,41 +1,42 @@ -package db.migration; - -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.Statement; - -import org.flywaydb.core.api.migration.BaseJavaMigration; -import org.flywaydb.core.api.migration.Context; - -public class V004__UPDATE_REVIEWS extends BaseJavaMigration { - - @Override - public Integer getChecksum() { - // implement this if needed to detect changes - return super.getChecksum(); - } - - public void migrate(Context context) throws Exception { - - // either create a Spring JdbcTemplate or use native JDBC - // new JdbcTemplate(new SingleConnectionDataSource(context.getConnection(), - // true)); - - try (Statement select = context.getConnection().createStatement()) { - try (ResultSet rows = select.executeQuery("SELECT id, name, publisher FROM book")) { - while (rows.next()) { - Long id = rows.getLong(1); - String bookName = rows.getString(2); - String publisher = rows.getString(3); - try (PreparedStatement preparedUpdate = context.getConnection() - .prepareStatement("UPDATE book SET name = ?, publisher = ? WHERE id = ?")) { - preparedUpdate.setString(1, bookName.toUpperCase()); - preparedUpdate.setString(2, publisher.toUpperCase()); - preparedUpdate.setLong(3, id); - preparedUpdate.executeUpdate(); - } - } - } - } - } -} +package db.migration; + +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.Statement; +import org.flywaydb.core.api.migration.BaseJavaMigration; +import org.flywaydb.core.api.migration.Context; + +public class V004__UPDATE_REVIEWS extends BaseJavaMigration { + + @Override + public Integer getChecksum() { + // implement this if needed to detect changes + return super.getChecksum(); + } + + public void migrate(Context context) throws Exception { + + // either create a Spring JdbcTemplate or use native JDBC + // new JdbcTemplate(new SingleConnectionDataSource(context.getConnection(), + // true)); + + try (Statement select = context.getConnection().createStatement()) { + try (ResultSet rows = select.executeQuery("SELECT id, name, publisher FROM book")) { + while (rows.next()) { + Long id = rows.getLong(1); + String bookName = rows.getString(2); + String publisher = rows.getString(3); + try (PreparedStatement preparedUpdate = + context + .getConnection() + .prepareStatement("UPDATE book SET name = ?, publisher = ? WHERE id = ?")) { + preparedUpdate.setString(1, bookName.toUpperCase()); + preparedUpdate.setString(2, publisher.toUpperCase()); + preparedUpdate.setLong(3, id); + preparedUpdate.executeUpdate(); + } + } + } + } + } +} diff --git a/spring-boot-hibernate-flyway-best-practices/src/main/java/de/rieckpil/blog/BestReviewedBooks.java b/spring-boot-hibernate-flyway-best-practices/src/main/java/de/rieckpil/blog/BestReviewedBooks.java index e704da3c..19c5ca15 100644 --- a/spring-boot-hibernate-flyway-best-practices/src/main/java/de/rieckpil/blog/BestReviewedBooks.java +++ b/spring-boot-hibernate-flyway-best-practices/src/main/java/de/rieckpil/blog/BestReviewedBooks.java @@ -1,27 +1,25 @@ -package de.rieckpil.blog; - -import java.math.BigDecimal; - -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; - -import org.hibernate.annotations.Immutable; - -import lombok.Data; - -@Data -@Entity -@Immutable -public class BestReviewedBooks { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long bookId; - private String bookName; - private Long totalReviews; - private BigDecimal avgStars; - private Integer maxStars; - private Integer minStars; -} +package de.rieckpil.blog; + +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import java.math.BigDecimal; +import lombok.Data; +import org.hibernate.annotations.Immutable; + +@Data +@Entity +@Immutable +public class BestReviewedBooks { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long bookId; + + private String bookName; + private Long totalReviews; + private BigDecimal avgStars; + private Integer maxStars; + private Integer minStars; +} diff --git a/spring-boot-hibernate-flyway-best-practices/src/main/java/de/rieckpil/blog/BestReviewedBooksRepository.java b/spring-boot-hibernate-flyway-best-practices/src/main/java/de/rieckpil/blog/BestReviewedBooksRepository.java index 962558a6..265834e8 100644 --- a/spring-boot-hibernate-flyway-best-practices/src/main/java/de/rieckpil/blog/BestReviewedBooksRepository.java +++ b/spring-boot-hibernate-flyway-best-practices/src/main/java/de/rieckpil/blog/BestReviewedBooksRepository.java @@ -1,7 +1,5 @@ -package de.rieckpil.blog; - -import org.springframework.data.jpa.repository.JpaRepository; - -public interface BestReviewedBooksRepository extends JpaRepository { - -} +package de.rieckpil.blog; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface BestReviewedBooksRepository extends JpaRepository {} diff --git a/spring-boot-hibernate-flyway-best-practices/src/main/java/de/rieckpil/blog/Book.java b/spring-boot-hibernate-flyway-best-practices/src/main/java/de/rieckpil/blog/Book.java index 13c47797..3e180de7 100644 --- a/spring-boot-hibernate-flyway-best-practices/src/main/java/de/rieckpil/blog/Book.java +++ b/spring-boot-hibernate-flyway-best-practices/src/main/java/de/rieckpil/blog/Book.java @@ -1,33 +1,30 @@ -package de.rieckpil.blog; - -import java.time.Instant; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; - -import lombok.Data; - -@Data -@Entity -public class Book { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @Column(nullable = false) - private String name; - - @Column(nullable = false) - private String publisher; - - @Column(nullable = false) - private Instant publishedAt; - - @Column(nullable = false) - private Integer pages; - -} +package de.rieckpil.blog; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import java.time.Instant; +import lombok.Data; + +@Data +@Entity +public class Book { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(nullable = false) + private String name; + + @Column(nullable = false) + private String publisher; + + @Column(nullable = false) + private Instant publishedAt; + + @Column(nullable = false) + private Integer pages; +} diff --git a/spring-boot-hibernate-flyway-best-practices/src/main/java/de/rieckpil/blog/Review.java b/spring-boot-hibernate-flyway-best-practices/src/main/java/de/rieckpil/blog/Review.java index 1b27b245..c545357b 100644 --- a/spring-boot-hibernate-flyway-best-practices/src/main/java/de/rieckpil/blog/Review.java +++ b/spring-boot-hibernate-flyway-best-practices/src/main/java/de/rieckpil/blog/Review.java @@ -1,36 +1,33 @@ -package de.rieckpil.blog; - -import java.time.Instant; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.ManyToOne; - -import lombok.Data; - -@Data -@Entity -public class Review { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @ManyToOne - private Book book; - - @Column(nullable = false) - private String reviewText; - - @Column(nullable = false) - private String reviewerEmail; - - @Column(nullable = false) - private Instant reviewDate; - - @Column(nullable = false) - private Integer stars; -} +package de.rieckpil.blog; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.ManyToOne; +import java.time.Instant; +import lombok.Data; + +@Data +@Entity +public class Review { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ManyToOne private Book book; + + @Column(nullable = false) + private String reviewText; + + @Column(nullable = false) + private String reviewerEmail; + + @Column(nullable = false) + private Instant reviewDate; + + @Column(nullable = false) + private Integer stars; +} diff --git a/spring-boot-hibernate-flyway-best-practices/src/main/java/de/rieckpil/blog/SpringBootHibernateFlywayBestPracticesApplication.java b/spring-boot-hibernate-flyway-best-practices/src/main/java/de/rieckpil/blog/SpringBootHibernateFlywayBestPracticesApplication.java index b01206df..3d727409 100644 --- a/spring-boot-hibernate-flyway-best-practices/src/main/java/de/rieckpil/blog/SpringBootHibernateFlywayBestPracticesApplication.java +++ b/spring-boot-hibernate-flyway-best-practices/src/main/java/de/rieckpil/blog/SpringBootHibernateFlywayBestPracticesApplication.java @@ -1,27 +1,24 @@ -package de.rieckpil.blog; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.CommandLineRunner; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; - -@SpringBootApplication -public class SpringBootHibernateFlywayBestPracticesApplication implements CommandLineRunner { - - @Autowired - private BestReviewedBooksRepository bestReviewedBookRepository; - - public static void main(String[] args) { - SpringApplication.run(SpringBootHibernateFlywayBestPracticesApplication.class, args); - } - - @Override - public void run(String... args) throws Exception { - - for (BestReviewedBooks reviewedBook : bestReviewedBookRepository.findAll()) { - System.out.println(reviewedBook); - } - - } - -} +package de.rieckpil.blog; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class SpringBootHibernateFlywayBestPracticesApplication implements CommandLineRunner { + + @Autowired private BestReviewedBooksRepository bestReviewedBookRepository; + + public static void main(String[] args) { + SpringApplication.run(SpringBootHibernateFlywayBestPracticesApplication.class, args); + } + + @Override + public void run(String... args) throws Exception { + + for (BestReviewedBooks reviewedBook : bestReviewedBookRepository.findAll()) { + System.out.println(reviewedBook); + } + } +} diff --git a/spring-boot-hibernate-flyway-best-practices/src/test/java/de/rieckpil/blog/SpringBootHibernateFlywayBestPracticesApplicationTests.java b/spring-boot-hibernate-flyway-best-practices/src/test/java/de/rieckpil/blog/SpringBootHibernateFlywayBestPracticesApplicationTests.java index dbd7c8cf..10fc3712 100644 --- a/spring-boot-hibernate-flyway-best-practices/src/test/java/de/rieckpil/blog/SpringBootHibernateFlywayBestPracticesApplicationTests.java +++ b/spring-boot-hibernate-flyway-best-practices/src/test/java/de/rieckpil/blog/SpringBootHibernateFlywayBestPracticesApplicationTests.java @@ -1,7 +1,6 @@ package de.rieckpil.blog; import org.junit.ClassRule; -import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; @@ -14,28 +13,28 @@ @RunWith(SpringRunner.class) @SpringBootTest -@ContextConfiguration(initializers = SpringBootHibernateFlywayBestPracticesApplicationTests.Initializer.class) +@ContextConfiguration( + initializers = SpringBootHibernateFlywayBestPracticesApplicationTests.Initializer.class) public class SpringBootHibernateFlywayBestPracticesApplicationTests { - @ClassRule - public static PostgreSQLContainer postgreSQLContainer = new PostgreSQLContainer() - .withDatabaseName("postgres") - .withPassword("postgres") - .withUsername("username"); + @ClassRule + public static PostgreSQLContainer postgreSQLContainer = + new PostgreSQLContainer() + .withDatabaseName("postgres") + .withPassword("postgres") + .withUsername("username"); - static class Initializer - implements ApplicationContextInitializer { - public void initialize(ConfigurableApplicationContext configurableApplicationContext) { - TestPropertyValues.of( - "spring.datasource.url=" + postgreSQLContainer.getJdbcUrl(), - "spring.datasource.username=" + postgreSQLContainer.getUsername(), - "spring.datasource.password=" + postgreSQLContainer.getPassword() - ).applyTo(configurableApplicationContext.getEnvironment()); - } - } - - @Test - public void contextLoads() { + static class Initializer + implements ApplicationContextInitializer { + public void initialize(ConfigurableApplicationContext configurableApplicationContext) { + TestPropertyValues.of( + "spring.datasource.url=" + postgreSQLContainer.getJdbcUrl(), + "spring.datasource.username=" + postgreSQLContainer.getUsername(), + "spring.datasource.password=" + postgreSQLContainer.getPassword()) + .applyTo(configurableApplicationContext.getEnvironment()); } + } + @Test + public void contextLoads() {} } diff --git a/spring-boot-integration-tests-testcontainers/pom.xml b/spring-boot-integration-tests-testcontainers/pom.xml index 67398a0d..7ed3114f 100644 --- a/spring-boot-integration-tests-testcontainers/pom.xml +++ b/spring-boot-integration-tests-testcontainers/pom.xml @@ -3,39 +3,19 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - de.rieckpil.blog + + de.rieckpil.blog + blog-parent + 0.0.1-SNAPSHOT + ../pom.xml + + spring-boot-integration-tests-testcontainers 0.0.1-SNAPSHOT jar Demo project for Spring Boot Integration test with Testcontainers - - org.springframework.boot - spring-boot-starter-parent - 2.5.5 - - - - - UTF-8 - UTF-8 - 11 - 1.16.0 - - - - - - org.testcontainers - testcontainers-bom - ${testcontainers.version} - pom - import - - - - org.springframework.boot @@ -77,19 +57,6 @@ org.springframework.boot spring-boot-maven-plugin - - org.apache.maven.plugins - maven-failsafe-plugin - 3.0.0-M4 - - - - integration-test - verify - - - - diff --git a/spring-boot-integration-tests-testcontainers/src/main/java/de/rieckpil/blog/Person.java b/spring-boot-integration-tests-testcontainers/src/main/java/de/rieckpil/blog/Person.java index ca621bd9..d185e770 100644 --- a/spring-boot-integration-tests-testcontainers/src/main/java/de/rieckpil/blog/Person.java +++ b/spring-boot-integration-tests-testcontainers/src/main/java/de/rieckpil/blog/Person.java @@ -1,9 +1,9 @@ package de.rieckpil.blog; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; @Entity public class Person { @@ -14,9 +14,7 @@ public class Person { private String name; - public Person() { - - } + public Person() {} public Person(Long id, String name) { this.id = id; @@ -39,4 +37,3 @@ public void setName(String name) { this.name = name; } } - diff --git a/spring-boot-integration-tests-testcontainers/src/main/java/de/rieckpil/blog/PersonRepository.java b/spring-boot-integration-tests-testcontainers/src/main/java/de/rieckpil/blog/PersonRepository.java index dc48b8de..6accf5ce 100644 --- a/spring-boot-integration-tests-testcontainers/src/main/java/de/rieckpil/blog/PersonRepository.java +++ b/spring-boot-integration-tests-testcontainers/src/main/java/de/rieckpil/blog/PersonRepository.java @@ -2,5 +2,4 @@ import org.springframework.data.jpa.repository.JpaRepository; -public interface PersonRepository extends JpaRepository { -} +public interface PersonRepository extends JpaRepository {} diff --git a/spring-boot-integration-tests-testcontainers/src/main/java/de/rieckpil/blog/PersonsController.java b/spring-boot-integration-tests-testcontainers/src/main/java/de/rieckpil/blog/PersonsController.java index 246dca22..f775a8b1 100644 --- a/spring-boot-integration-tests-testcontainers/src/main/java/de/rieckpil/blog/PersonsController.java +++ b/spring-boot-integration-tests-testcontainers/src/main/java/de/rieckpil/blog/PersonsController.java @@ -1,7 +1,6 @@ package de.rieckpil.blog; import java.util.List; - import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; @@ -27,8 +26,9 @@ public List getAllPersons() { @GetMapping("/{id}") public Person getPersonById(@PathVariable("id") Long id) { - return personRepository.findById(id).orElseThrow(() -> new NoPersonFoundException("Person with id:" + id + - " not found")); + return personRepository + .findById(id) + .orElseThrow(() -> new NoPersonFoundException("Person with id:" + id + " not found")); } @PostMapping diff --git a/spring-boot-integration-tests-testcontainers/src/test/java/de/rieckpil/blog/AlternativeJUnit5ApplicationTest.java b/spring-boot-integration-tests-testcontainers/src/test/java/de/rieckpil/blog/AlternativeJUnit5ApplicationTest.java index 8cb28a53..6564639e 100644 --- a/spring-boot-integration-tests-testcontainers/src/test/java/de/rieckpil/blog/AlternativeJUnit5ApplicationTest.java +++ b/spring-boot-integration-tests-testcontainers/src/test/java/de/rieckpil/blog/AlternativeJUnit5ApplicationTest.java @@ -17,22 +17,22 @@ class AlternativeJUnit5ApplicationTest { @Container - static PostgreSQLContainer postgreSQLContainer = new PostgreSQLContainer<>("postgres:12") - .withPassword("inmemory") - .withUsername("inmemory"); + static PostgreSQLContainer postgreSQLContainer = + new PostgreSQLContainer<>("postgres:16.1").withPassword("inmemory").withUsername("inmemory"); - public static class Initializer implements ApplicationContextInitializer { + public static class Initializer + implements ApplicationContextInitializer { @Override public void initialize(ConfigurableApplicationContext configurableApplicationContext) { - TestPropertyValues values = TestPropertyValues.of( - "spring.datasource.url=" + postgreSQLContainer.getJdbcUrl(), - "spring.datasource.password=" + postgreSQLContainer.getPassword(), - "spring.datasource.username=" + postgreSQLContainer.getUsername()); + TestPropertyValues values = + TestPropertyValues.of( + "spring.datasource.url=" + postgreSQLContainer.getJdbcUrl(), + "spring.datasource.password=" + postgreSQLContainer.getPassword(), + "spring.datasource.username=" + postgreSQLContainer.getUsername()); values.applyTo(configurableApplicationContext); } } @Test - void contextLoads() { - } + void contextLoads() {} } diff --git a/spring-boot-integration-tests-testcontainers/src/test/java/de/rieckpil/blog/ApplicationIT.java b/spring-boot-integration-tests-testcontainers/src/test/java/de/rieckpil/blog/ApplicationIT.java index 9370431a..0534b725 100644 --- a/spring-boot-integration-tests-testcontainers/src/test/java/de/rieckpil/blog/ApplicationIT.java +++ b/spring-boot-integration-tests-testcontainers/src/test/java/de/rieckpil/blog/ApplicationIT.java @@ -1,15 +1,14 @@ package de.rieckpil.blog; -import org.junit.jupiter.api.Test; -import org.testcontainers.containers.PostgreSQLContainer; -import org.testcontainers.junit.jupiter.Container; -import org.testcontainers.junit.jupiter.Testcontainers; +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.DynamicPropertyRegistry; import org.springframework.test.context.DynamicPropertySource; - -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.testcontainers.containers.PostgreSQLContainer; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; // JUnit 5 example with Spring Boot >= 2.2.6 @Testcontainers @@ -17,9 +16,8 @@ public class ApplicationIT { @Container - public static PostgreSQLContainer postgreSQLContainer = new PostgreSQLContainer() - .withPassword("inmemory") - .withUsername("inmemory"); + public static PostgreSQLContainer postgreSQLContainer = + new PostgreSQLContainer("postgres:16.1").withPassword("inmemory").withUsername("inmemory"); @DynamicPropertySource static void postgresqlProperties(DynamicPropertyRegistry registry) { @@ -29,7 +27,5 @@ static void postgresqlProperties(DynamicPropertyRegistry registry) { } @Test - public void contextLoads() { - } - + public void contextLoads() {} } diff --git a/spring-boot-integration-tests-testcontainers/src/test/java/de/rieckpil/blog/BasicContainerTest.java b/spring-boot-integration-tests-testcontainers/src/test/java/de/rieckpil/blog/BasicContainerTest.java index 84844bf1..5b4ef15a 100644 --- a/spring-boot-integration-tests-testcontainers/src/test/java/de/rieckpil/blog/BasicContainerTest.java +++ b/spring-boot-integration-tests-testcontainers/src/test/java/de/rieckpil/blog/BasicContainerTest.java @@ -2,7 +2,7 @@ import java.io.IOException; import java.util.Map; - +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.testcontainers.containers.BindMode; import org.testcontainers.containers.GenericContainer; @@ -11,25 +11,26 @@ import org.testcontainers.junit.jupiter.Testcontainers; import org.testcontainers.utility.DockerImageName; +@Disabled("Only for demonstration purposes") @Testcontainers class BasicContainerTest { @Container static GenericContainer keycloak = - new GenericContainer<>(DockerImageName.parse("jboss/keycloak:11.0.0")) - .waitingFor(Wait.forHttp("/auth").forStatusCode(200)) - .withExposedPorts(8080) - .withClasspathResourceMapping("/config/test.txt", "/tmp/test.txt", BindMode.READ_WRITE) - .withEnv(Map.of( - "KEYCLOAK_USER", "testcontainers", - "KEYCLOAK_PASSWORD", "testcontainers", - "DB_VENDOR", "h2" - )); + new GenericContainer<>(DockerImageName.parse("jboss/keycloak:16.1.1")) + .waitingFor(Wait.forHttp("/auth").forStatusCode(200)) + .withExposedPorts(8080) + .withClasspathResourceMapping("/config/test.txt", "/tmp/test.txt", BindMode.READ_WRITE) + .withEnv( + Map.of( + "KEYCLOAK_USER", "testcontainers", + "KEYCLOAK_PASSWORD", "testcontainers", + "DB_VENDOR", "h2")); @Test void testWithKeycloak() throws IOException, InterruptedException { - org.testcontainers.containers.Container.ExecResult execResult = keycloak - .execInContainer("/bin/sh", "-c", "echo \"Admin user is $KEYCLOAK_USER\""); + org.testcontainers.containers.Container.ExecResult execResult = + keycloak.execInContainer("/bin/sh", "-c", "echo \"Admin user is $KEYCLOAK_USER\""); System.out.println("Result: " + execResult.getStdout()); System.out.println("Keycloak is running on port: " + keycloak.getMappedPort(8080)); } diff --git a/spring-boot-integration-tests-testcontainers/src/test/java/de/rieckpil/blog/CreatePersonIT.java b/spring-boot-integration-tests-testcontainers/src/test/java/de/rieckpil/blog/CreatePersonIT.java index a8726af9..77d0db5f 100644 --- a/spring-boot-integration-tests-testcontainers/src/test/java/de/rieckpil/blog/CreatePersonIT.java +++ b/spring-boot-integration-tests-testcontainers/src/test/java/de/rieckpil/blog/CreatePersonIT.java @@ -1,20 +1,19 @@ package de.rieckpil.blog; -import org.junit.jupiter.api.Test; -import org.testcontainers.containers.PostgreSQLContainer; -import org.testcontainers.junit.jupiter.Container; -import org.testcontainers.junit.jupiter.Testcontainers; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.http.ResponseEntity; import org.springframework.test.context.DynamicPropertyRegistry; import org.springframework.test.context.DynamicPropertySource; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.testcontainers.containers.PostgreSQLContainer; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; // JUnit 5 example with Spring Boot >= 2.2.6 @Testcontainers @@ -22,15 +21,12 @@ public class CreatePersonIT { @Container - public static PostgreSQLContainer postgreSQLContainer = new PostgreSQLContainer() - .withPassword("inmemory") - .withUsername("inmemory"); + public static PostgreSQLContainer postgreSQLContainer = + new PostgreSQLContainer("postgres:16.1").withPassword("inmemory").withUsername("inmemory"); - @Autowired - private PersonRepository personRepository; + @Autowired private PersonRepository personRepository; - @Autowired - public TestRestTemplate testRestTemplate; + @Autowired public TestRestTemplate testRestTemplate; @DynamicPropertySource static void postgresqlProperties(DynamicPropertyRegistry registry) { @@ -47,7 +43,8 @@ public void testRestEndpointForAllPersons() { assertEquals(0, personRepository.findAll().size()); - ResponseEntity result = testRestTemplate.postForEntity("/api/persons", requestBody, Person.class); + ResponseEntity result = + testRestTemplate.postForEntity("/api/persons", requestBody, Person.class); assertNotNull(result); assertNotNull(result.getBody().getId()); @@ -55,5 +52,4 @@ public void testRestEndpointForAllPersons() { assertEquals(1, personRepository.findAll().size()); assertEquals("rieckpil", personRepository.findAll().get(0).getName()); } - } diff --git a/spring-boot-integration-tests-testcontainers/src/test/java/de/rieckpil/blog/DeletePersonIT.java b/spring-boot-integration-tests-testcontainers/src/test/java/de/rieckpil/blog/DeletePersonIT.java index 9dd2b3b0..613f8119 100644 --- a/spring-boot-integration-tests-testcontainers/src/test/java/de/rieckpil/blog/DeletePersonIT.java +++ b/spring-boot-integration-tests-testcontainers/src/test/java/de/rieckpil/blog/DeletePersonIT.java @@ -1,10 +1,10 @@ package de.rieckpil.blog; -import org.junit.jupiter.api.Test; -import org.testcontainers.containers.PostgreSQLContainer; -import org.testcontainers.junit.jupiter.Container; -import org.testcontainers.junit.jupiter.Testcontainers; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.util.TestPropertyValues; @@ -13,10 +13,9 @@ import org.springframework.context.ConfigurableApplicationContext; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.jdbc.Sql; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.testcontainers.containers.PostgreSQLContainer; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; // JUnit 5 example with Spring Boot < 2.2.6 @Testcontainers @@ -25,25 +24,23 @@ public class DeletePersonIT { @Container - public static PostgreSQLContainer postgreSQLContainer = new PostgreSQLContainer() - .withPassword("inmemory") - .withUsername("inmemory"); + public static PostgreSQLContainer postgreSQLContainer = + new PostgreSQLContainer("postgres:16.1").withPassword("inmemory").withUsername("inmemory"); - @Autowired - private PersonRepository personRepository; + @Autowired private PersonRepository personRepository; - @Autowired - public TestRestTemplate testRestTemplate; + @Autowired public TestRestTemplate testRestTemplate; - public static class Initializer implements ApplicationContextInitializer { + public static class Initializer + implements ApplicationContextInitializer { @Override public void initialize(ConfigurableApplicationContext configurableApplicationContext) { - TestPropertyValues values = TestPropertyValues.of( - "spring.datasource.url=" + postgreSQLContainer.getJdbcUrl(), - "spring.datasource.password=" + postgreSQLContainer.getPassword(), - "spring.datasource.username=" + postgreSQLContainer.getUsername() - ); + TestPropertyValues values = + TestPropertyValues.of( + "spring.datasource.url=" + postgreSQLContainer.getJdbcUrl(), + "spring.datasource.password=" + postgreSQLContainer.getPassword(), + "spring.datasource.username=" + postgreSQLContainer.getUsername()); values.applyTo(configurableApplicationContext); } } @@ -54,6 +51,5 @@ public void testDeletePerson() { testRestTemplate.delete("/api/persons/1"); assertEquals(3, personRepository.findAll().size()); assertFalse(personRepository.findAll().contains("Phil")); - } } diff --git a/spring-boot-integration-tests-testcontainers/src/test/java/de/rieckpil/blog/GetAllPersonsIT.java b/spring-boot-integration-tests-testcontainers/src/test/java/de/rieckpil/blog/GetAllPersonsIT.java index 742bd993..7d41394d 100644 --- a/spring-boot-integration-tests-testcontainers/src/test/java/de/rieckpil/blog/GetAllPersonsIT.java +++ b/spring-boot-integration-tests-testcontainers/src/test/java/de/rieckpil/blog/GetAllPersonsIT.java @@ -1,14 +1,15 @@ package de.rieckpil.blog; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment; + import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; - import org.junit.ClassRule; import org.junit.Test; import org.junit.runner.RunWith; -import org.testcontainers.containers.PostgreSQLContainer; - import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.util.TestPropertyValues; @@ -19,10 +20,7 @@ import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.jdbc.Sql; import org.springframework.test.context.junit4.SpringRunner; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.testcontainers.containers.PostgreSQLContainer; // JUnit 4.12 example @RunWith(SpringRunner.class) @@ -31,22 +29,21 @@ public class GetAllPersonsIT { @ClassRule - public static PostgreSQLContainer postgreSQLContainer = new PostgreSQLContainer() - .withPassword("inmemory") - .withUsername("inmemory"); + public static PostgreSQLContainer postgreSQLContainer = + new PostgreSQLContainer("postgres:16.1").withPassword("inmemory").withUsername("inmemory"); - @Autowired - public TestRestTemplate testRestTemplate; + @Autowired public TestRestTemplate testRestTemplate; - public static class Initializer implements ApplicationContextInitializer { + public static class Initializer + implements ApplicationContextInitializer { @Override public void initialize(ConfigurableApplicationContext configurableApplicationContext) { - TestPropertyValues values = TestPropertyValues.of( - "spring.datasource.url=" + postgreSQLContainer.getJdbcUrl(), - "spring.datasource.password=" + postgreSQLContainer.getPassword(), - "spring.datasource.username=" + postgreSQLContainer.getUsername() - ); + TestPropertyValues values = + TestPropertyValues.of( + "spring.datasource.url=" + postgreSQLContainer.getJdbcUrl(), + "spring.datasource.password=" + postgreSQLContainer.getPassword(), + "spring.datasource.username=" + postgreSQLContainer.getUsername()); values.applyTo(configurableApplicationContext); } } @@ -60,9 +57,10 @@ public void testGetAllPersons() { List resultList = Arrays.asList(result.getBody()); assertEquals(4, resultList.size()); - assertTrue(resultList.stream().map(p -> p.getName()).collect(Collectors.toList()).containsAll(Arrays.asList - ("Mike", "Phil", "Duke", "Tom"))); - + assertTrue( + resultList.stream() + .map(p -> p.getName()) + .collect(Collectors.toList()) + .containsAll(Arrays.asList("Mike", "Phil", "Duke", "Tom"))); } - } diff --git a/spring-boot-integration-tests-testcontainers/src/test/java/de/rieckpil/blog/GetPersonByIdIT.java b/spring-boot-integration-tests-testcontainers/src/test/java/de/rieckpil/blog/GetPersonByIdIT.java index a838b370..1c155619 100644 --- a/spring-boot-integration-tests-testcontainers/src/test/java/de/rieckpil/blog/GetPersonByIdIT.java +++ b/spring-boot-integration-tests-testcontainers/src/test/java/de/rieckpil/blog/GetPersonByIdIT.java @@ -1,10 +1,12 @@ package de.rieckpil.blog; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.springframework.boot.test.context.SpringBootTest.*; + import org.junit.ClassRule; import org.junit.Test; import org.junit.runner.RunWith; -import org.testcontainers.containers.PostgreSQLContainer; - import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.util.TestPropertyValues; @@ -16,10 +18,7 @@ import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.jdbc.Sql; import org.springframework.test.context.junit4.SpringRunner; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; -import static org.springframework.boot.test.context.SpringBootTest.*; +import org.testcontainers.containers.PostgreSQLContainer; // JUnit 4.12 example @RunWith(SpringRunner.class) @@ -28,25 +27,23 @@ public class GetPersonByIdIT { @ClassRule - public static PostgreSQLContainer postgreSQLContainer = new PostgreSQLContainer() - .withPassword("inmemory") - .withUsername("inmemory"); + public static PostgreSQLContainer postgreSQLContainer = + new PostgreSQLContainer("postgres:16.1").withPassword("inmemory").withUsername("inmemory"); - @Autowired - private PersonRepository personRepository; + @Autowired private PersonRepository personRepository; - @Autowired - public TestRestTemplate testRestTemplate; + @Autowired public TestRestTemplate testRestTemplate; - public static class Initializer implements ApplicationContextInitializer { + public static class Initializer + implements ApplicationContextInitializer { @Override public void initialize(ConfigurableApplicationContext configurableApplicationContext) { - TestPropertyValues values = TestPropertyValues.of( - "spring.datasource.url=" + postgreSQLContainer.getJdbcUrl(), - "spring.datasource.password=" + postgreSQLContainer.getPassword(), - "spring.datasource.username=" + postgreSQLContainer.getUsername() - ); + TestPropertyValues values = + TestPropertyValues.of( + "spring.datasource.url=" + postgreSQLContainer.getJdbcUrl(), + "spring.datasource.password=" + postgreSQLContainer.getPassword(), + "spring.datasource.username=" + postgreSQLContainer.getUsername()); values.applyTo(configurableApplicationContext); } } @@ -59,7 +56,6 @@ public void testNotExistingPersonByIdShouldReturn404() { assertEquals(HttpStatus.NOT_FOUND, result.getStatusCode()); assertNull(result.getBody().getName()); assertNull(result.getBody().getId()); - } @Test @@ -73,5 +69,4 @@ public void testExistingPersonById() { assertEquals("Phil", result.getBody().getName()); assertEquals(1l, result.getBody().getId().longValue()); } - } diff --git a/spring-boot-integration-tests-testcontainers/src/test/java/de/rieckpil/blog/JUnit4ApplicationTest.java b/spring-boot-integration-tests-testcontainers/src/test/java/de/rieckpil/blog/JUnit4ApplicationTest.java index 8b9166de..8cf1419e 100644 --- a/spring-boot-integration-tests-testcontainers/src/test/java/de/rieckpil/blog/JUnit4ApplicationTest.java +++ b/spring-boot-integration-tests-testcontainers/src/test/java/de/rieckpil/blog/JUnit4ApplicationTest.java @@ -17,24 +17,23 @@ public class JUnit4ApplicationTest { @ClassRule - public static PostgreSQLContainer postgreSQLContainer = new PostgreSQLContainer<>("postgres:12") - .withPassword("inmemory") - .withUsername("inmemory"); + public static PostgreSQLContainer postgreSQLContainer = + new PostgreSQLContainer<>("postgres:16.1").withPassword("inmemory").withUsername("inmemory"); - public static class Initializer implements ApplicationContextInitializer { + public static class Initializer + implements ApplicationContextInitializer { @Override public void initialize(ConfigurableApplicationContext configurableApplicationContext) { - TestPropertyValues values = TestPropertyValues.of( - "spring.datasource.url=" + postgreSQLContainer.getJdbcUrl(), - "spring.datasource.password=" + postgreSQLContainer.getPassword(), - "spring.datasource.username=" + postgreSQLContainer.getUsername() - ); + TestPropertyValues values = + TestPropertyValues.of( + "spring.datasource.url=" + postgreSQLContainer.getJdbcUrl(), + "spring.datasource.password=" + postgreSQLContainer.getPassword(), + "spring.datasource.username=" + postgreSQLContainer.getUsername()); values.applyTo(configurableApplicationContext); } } @Test - public void contextLoads() { - } + public void contextLoads() {} } diff --git a/spring-boot-integration-tests-testcontainers/src/test/java/de/rieckpil/blog/JUnit5ApplicationTest.java b/spring-boot-integration-tests-testcontainers/src/test/java/de/rieckpil/blog/JUnit5ApplicationTest.java index aa3870e6..83e8c89e 100644 --- a/spring-boot-integration-tests-testcontainers/src/test/java/de/rieckpil/blog/JUnit5ApplicationTest.java +++ b/spring-boot-integration-tests-testcontainers/src/test/java/de/rieckpil/blog/JUnit5ApplicationTest.java @@ -13,9 +13,8 @@ class JUnit5ApplicationTest { @Container - static PostgreSQLContainer postgreSQLContainer = new PostgreSQLContainer<>("postgres:12") - .withPassword("inmemory") - .withUsername("inmemory"); + static PostgreSQLContainer postgreSQLContainer = + new PostgreSQLContainer<>("postgres:16.1").withPassword("inmemory").withUsername("inmemory"); @DynamicPropertySource static void postgresqlProperties(DynamicPropertyRegistry registry) { @@ -25,6 +24,5 @@ static void postgresqlProperties(DynamicPropertyRegistry registry) { } @Test - void contextLoads() { - } + void contextLoads() {} } diff --git a/spring-boot-integration-tests-testcontainers/src/test/java/de/rieckpil/blog/ModuleContainerTest.java b/spring-boot-integration-tests-testcontainers/src/test/java/de/rieckpil/blog/ModuleContainerTest.java index 81e7efae..2c1cb3c7 100644 --- a/spring-boot-integration-tests-testcontainers/src/test/java/de/rieckpil/blog/ModuleContainerTest.java +++ b/spring-boot-integration-tests-testcontainers/src/test/java/de/rieckpil/blog/ModuleContainerTest.java @@ -9,11 +9,12 @@ class ModuleContainerTest { @Container - static PostgreSQLContainer database = new PostgreSQLContainer<>("postgres:12") - .withUsername("duke") - .withPassword("secret") - .withInitScript("config/INIT.sql") - .withDatabaseName("tescontainers"); + static PostgreSQLContainer database = + new PostgreSQLContainer<>("postgres:16.1") + .withUsername("duke") + .withPassword("secret") + .withInitScript("config/INIT.sql") + .withDatabaseName("tescontainers"); @Test void testPostgreSQLModule() { diff --git a/spring-boot-integration-tests-wiremock/pom.xml b/spring-boot-integration-tests-wiremock/pom.xml index ebd414c7..f70981f4 100644 --- a/spring-boot-integration-tests-wiremock/pom.xml +++ b/spring-boot-integration-tests-wiremock/pom.xml @@ -1,6 +1,5 @@ - + 4.0.0 @@ -19,13 +18,6 @@ 2.35.0 - - - jitpack.io - https://jitpack.io - - - org.springframework.boot @@ -75,4 +67,11 @@ test + + + + jitpack.io + https://jitpack.io + + diff --git a/spring-boot-integration-tests-wiremock/src/main/java/de/rieckpil/blog/Application.java b/spring-boot-integration-tests-wiremock/src/main/java/de/rieckpil/blog/Application.java index bd5e4c56..6511f3c1 100644 --- a/spring-boot-integration-tests-wiremock/src/main/java/de/rieckpil/blog/Application.java +++ b/spring-boot-integration-tests-wiremock/src/main/java/de/rieckpil/blog/Application.java @@ -9,5 +9,4 @@ public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } - } diff --git a/spring-boot-integration-tests-wiremock/src/main/java/de/rieckpil/blog/TodoController.java b/spring-boot-integration-tests-wiremock/src/main/java/de/rieckpil/blog/TodoController.java index 2ff0d3d6..f224a9d9 100644 --- a/spring-boot-integration-tests-wiremock/src/main/java/de/rieckpil/blog/TodoController.java +++ b/spring-boot-integration-tests-wiremock/src/main/java/de/rieckpil/blog/TodoController.java @@ -19,11 +19,11 @@ public TodoController(WebClient todoWebClient) { @GetMapping public ArrayNode getAllTodos() { return this.todoWebClient - .get() - .uri("/todos") - .header("X-Auth", "duke") - .retrieve() - .bodyToMono(ArrayNode.class) - .block(); + .get() + .uri("/todos") + .header("X-Auth", "duke") + .retrieve() + .bodyToMono(ArrayNode.class) + .block(); } } diff --git a/spring-boot-integration-tests-wiremock/src/main/java/de/rieckpil/blog/WebClientConfig.java b/spring-boot-integration-tests-wiremock/src/main/java/de/rieckpil/blog/WebClientConfig.java index ed6a51c9..ba5842da 100644 --- a/spring-boot-integration-tests-wiremock/src/main/java/de/rieckpil/blog/WebClientConfig.java +++ b/spring-boot-integration-tests-wiremock/src/main/java/de/rieckpil/blog/WebClientConfig.java @@ -12,12 +12,11 @@ public class WebClientConfig { @Bean public WebClient todoWebClient( - @Value("${todo_base_url}") String todoBaseUrl, - WebClient.Builder webClientBuilder) { + @Value("${todo_base_url}") String todoBaseUrl, WebClient.Builder webClientBuilder) { return webClientBuilder - .baseUrl(todoBaseUrl) - .defaultHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE) - .build(); + .baseUrl(todoBaseUrl) + .defaultHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE) + .build(); } } diff --git a/spring-boot-integration-tests-wiremock/src/test/java/de/rieckpil/blog/ManualSetupIT.java b/spring-boot-integration-tests-wiremock/src/test/java/de/rieckpil/blog/ManualSetupIT.java index fc1a5732..7ce68dd7 100644 --- a/spring-boot-integration-tests-wiremock/src/test/java/de/rieckpil/blog/ManualSetupIT.java +++ b/spring-boot-integration-tests-wiremock/src/test/java/de/rieckpil/blog/ManualSetupIT.java @@ -1,10 +1,19 @@ package de.rieckpil.blog; +import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; +import static com.github.tomakehurst.wiremock.client.WireMock.equalTo; +import static com.github.tomakehurst.wiremock.client.WireMock.exactly; +import static com.github.tomakehurst.wiremock.client.WireMock.getRequestedFor; +import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + import com.github.tomakehurst.wiremock.WireMockServer; import com.github.tomakehurst.wiremock.client.WireMock; import com.github.tomakehurst.wiremock.core.WireMockConfiguration; import com.github.tomakehurst.wiremock.stubbing.ServeEvent; import com.github.tomakehurst.wiremock.verification.LoggedRequest; +import java.util.List; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; @@ -19,22 +28,11 @@ import org.springframework.test.context.DynamicPropertySource; import org.springframework.test.web.reactive.server.WebTestClient; -import java.util.List; - -import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; -import static com.github.tomakehurst.wiremock.client.WireMock.equalTo; -import static com.github.tomakehurst.wiremock.client.WireMock.exactly; -import static com.github.tomakehurst.wiremock.client.WireMock.getRequestedFor; -import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @TestMethodOrder(MethodOrderer.OrderAnnotation.class) class ManualSetupIT { - @Autowired - private WebTestClient webTestClient; + @Autowired private WebTestClient webTestClient; private static WireMockServer wireMockServer; @@ -45,8 +43,7 @@ static void overrideWebClientBaseUrl(DynamicPropertyRegistry dynamicPropertyRegi @BeforeAll static void startWireMock() { - wireMockServer = new WireMockServer(WireMockConfiguration.wireMockConfig() - .dynamicPort()); + wireMockServer = new WireMockServer(WireMockConfiguration.wireMockConfig().dynamicPort()); wireMockServer.start(); } @@ -73,83 +70,89 @@ void testWireMock() { @Order(1) void basicWireMockExample() { wireMockServer.stubFor( - WireMock.get("/todos") - .willReturn(aResponse() - .withHeader("Content-Type", MediaType.APPLICATION_JSON_VALUE) - .withBody("[]")) - ); + WireMock.get("/todos") + .willReturn( + aResponse() + .withHeader("Content-Type", MediaType.APPLICATION_JSON_VALUE) + .withBody("[]"))); this.webTestClient - .get() - .uri("/api/todos") - .exchange() - .expectStatus().isOk() - .expectBody().jsonPath("$.length()").isEqualTo(0); + .get() + .uri("/api/todos") + .exchange() + .expectStatus() + .isOk() + .expectBody() + .jsonPath("$.length()") + .isEqualTo(0); } @Test @Order(2) void wireMockRequestMatching() { wireMockServer.stubFor( - WireMock.get(WireMock.urlEqualTo("/users")) - .willReturn(aResponse() - .withHeader("Content-Type", MediaType.APPLICATION_JSON_VALUE) - .withBody("[]")) - ); + WireMock.get(WireMock.urlEqualTo("/users")) + .willReturn( + aResponse() + .withHeader("Content-Type", MediaType.APPLICATION_JSON_VALUE) + .withBody("[]"))); - this.webTestClient - .get() - .uri("/api/todos") - .exchange() - .expectStatus().is5xxServerError(); + this.webTestClient.get().uri("/api/todos").exchange().expectStatus().is5xxServerError(); } @Test void wireMockRequestMatchingPriority() { wireMockServer.stubFor( - WireMock.get(WireMock.urlEqualTo("/todos")) - .atPriority(1) - .willReturn(aResponse() - .withHeader("Content-Type", MediaType.APPLICATION_JSON_VALUE) - .withBody("[]")) - ); + WireMock.get(WireMock.urlEqualTo("/todos")) + .atPriority(1) + .willReturn( + aResponse() + .withHeader("Content-Type", MediaType.APPLICATION_JSON_VALUE) + .withBody("[]"))); wireMockServer.stubFor( - WireMock.get(WireMock.urlEqualTo("/todos")) - .atPriority(10) - .willReturn(aResponse() - .withStatus(500)) - ); + WireMock.get(WireMock.urlEqualTo("/todos")) + .atPriority(10) + .willReturn(aResponse().withStatus(500))); this.webTestClient - .get() - .uri("/api/todos") - .exchange() - .expectStatus().isOk() - .expectBody().jsonPath("$.length()").isEqualTo(0); + .get() + .uri("/api/todos") + .exchange() + .expectStatus() + .isOk() + .expectBody() + .jsonPath("$.length()") + .isEqualTo(0); } @Test void wireMockRequestMatchingWithData() { wireMockServer.stubFor( - WireMock.get(WireMock.urlEqualTo("/todos")) - .willReturn(aResponse() - .withHeader("Content-Type", MediaType.APPLICATION_JSON_VALUE) - .withBodyFile("todo-api/response-200.json") - .withFixedDelay(1_000)) - ); + WireMock.get(WireMock.urlEqualTo("/todos")) + .willReturn( + aResponse() + .withHeader("Content-Type", MediaType.APPLICATION_JSON_VALUE) + .withBodyFile("todo-api/response-200.json") + .withFixedDelay(1_000))); this.webTestClient - .get() - .uri("/api/todos") - .exchange() - .expectStatus().isOk() - .expectBody().jsonPath("$.length()").isEqualTo(3) - .jsonPath("$[0].title").isEqualTo("delectus aut autem"); - - wireMockServer.verify(exactly(1), getRequestedFor(urlEqualTo("/todos")) - .withHeader("Accept", equalTo("application/json")) - .withHeader("X-Auth", equalTo("duke"))); + .get() + .uri("/api/todos") + .exchange() + .expectStatus() + .isOk() + .expectBody() + .jsonPath("$.length()") + .isEqualTo(3) + .jsonPath("$[0].title") + .isEqualTo("delectus aut autem"); + + wireMockServer.verify( + exactly(1), + getRequestedFor(urlEqualTo("/todos")) + .withHeader("Accept", equalTo("application/json")) + .withHeader("X-Auth", equalTo("duke"))); List events = wireMockServer.getAllServeEvents(); diff --git a/spring-boot-integration-tests-wiremock/src/test/java/de/rieckpil/blog/TodoControllerIT.java b/spring-boot-integration-tests-wiremock/src/test/java/de/rieckpil/blog/TodoControllerIT.java index 0b17e3c8..b448fd05 100644 --- a/spring-boot-integration-tests-wiremock/src/test/java/de/rieckpil/blog/TodoControllerIT.java +++ b/spring-boot-integration-tests-wiremock/src/test/java/de/rieckpil/blog/TodoControllerIT.java @@ -1,5 +1,8 @@ package de.rieckpil.blog; +import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; +import static org.springframework.boot.test.context.SpringBootTest.*; + import com.github.tomakehurst.wiremock.WireMockServer; import com.github.tomakehurst.wiremock.client.WireMock; import org.eclipse.jetty.http.HttpStatus; @@ -12,64 +15,57 @@ import org.springframework.test.context.ContextConfiguration; import org.springframework.test.web.reactive.server.WebTestClient; -import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; -import static org.springframework.boot.test.context.SpringBootTest.*; - @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) @ContextConfiguration(initializers = {WireMockInitializer.class}) class TodoControllerIT { - @Autowired - private WireMockServer wireMockServer; + @Autowired private WireMockServer wireMockServer; - @Autowired - private WebTestClient webTestClient; + @Autowired private WebTestClient webTestClient; - @LocalServerPort - private Integer port; + @LocalServerPort private Integer port; @AfterEach public void afterEach() { this.wireMockServer.resetAll(); } -@Test -void testGetAllTodosShouldReturnDataFromClient() { - this.wireMockServer.stubFor( - WireMock.get("/todos") - .willReturn(aResponse() - .withHeader("Content-Type", MediaType.APPLICATION_JSON_VALUE) - .withBody("[{\"userId\": 1,\"id\": 1,\"title\": \"Learn Spring Boot 3.0\", \"completed\": false}," + - "{\"userId\": 1,\"id\": 2,\"title\": \"Learn WireMock\", \"completed\": true}]")) - ); + @Test + void testGetAllTodosShouldReturnDataFromClient() { + this.wireMockServer.stubFor( + WireMock.get("/todos") + .willReturn( + aResponse() + .withHeader("Content-Type", MediaType.APPLICATION_JSON_VALUE) + .withBody( + "[{\"userId\": 1,\"id\": 1,\"title\": \"Learn Spring Boot 3.0\", \"completed\": false}," + + "{\"userId\": 1,\"id\": 2,\"title\": \"Learn WireMock\", \"completed\": true}]"))); - this.webTestClient - .get() - .uri("/api/todos") - .exchange() - .expectStatus() - .is2xxSuccessful() - .expectBody() - .jsonPath("$[0].title") - .isEqualTo("Learn Spring Boot 3.0") - .jsonPath("$.length()") - .isEqualTo(2); -} + this.webTestClient + .get() + .uri("/api/todos") + .exchange() + .expectStatus() + .is2xxSuccessful() + .expectBody() + .jsonPath("$[0].title") + .isEqualTo("Learn Spring Boot 3.0") + .jsonPath("$.length()") + .isEqualTo(2); + } @Test void testGetAllTodosShouldPropagateErrorMessageFromClient() { this.wireMockServer.stubFor( - WireMock.get("/todos") - .willReturn(aResponse() - .withStatus(403) - .withFixedDelay(2000)) // milliseconds - ); + WireMock.get("/todos") + .willReturn(aResponse().withStatus(403).withFixedDelay(2000)) // milliseconds + ); this.webTestClient - .get() - .uri("http://localhost:" + port + "/api/todos") - .exchange() - .expectStatus() - .isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR_500); + .get() + .uri("http://localhost:" + port + "/api/todos") + .exchange() + .expectStatus() + .isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR_500); } } diff --git a/spring-boot-integration-tests-wiremock/src/test/java/de/rieckpil/blog/TodoControllerJUnit4IT.java b/spring-boot-integration-tests-wiremock/src/test/java/de/rieckpil/blog/TodoControllerJUnit4IT.java index aa99d509..8701b31c 100644 --- a/spring-boot-integration-tests-wiremock/src/test/java/de/rieckpil/blog/TodoControllerJUnit4IT.java +++ b/spring-boot-integration-tests-wiremock/src/test/java/de/rieckpil/blog/TodoControllerJUnit4IT.java @@ -1,5 +1,7 @@ package de.rieckpil.blog; +import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; + import com.github.tomakehurst.wiremock.client.WireMock; import com.github.tomakehurst.wiremock.core.WireMockConfiguration; import com.github.tomakehurst.wiremock.junit.WireMockClassRule; @@ -15,21 +17,17 @@ import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.reactive.server.WebTestClient; -import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; - @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) public class TodoControllerJUnit4IT { - @Autowired - private WebTestClient webTestClient; + @Autowired private WebTestClient webTestClient; @ClassRule public static WireMockClassRule wireMockClassRule = - new WireMockClassRule(WireMockConfiguration.wireMockConfig().dynamicPort()); + new WireMockClassRule(WireMockConfiguration.wireMockConfig().dynamicPort()); - @Rule - public WireMockClassRule methodRule = wireMockClassRule; + @Rule public WireMockClassRule methodRule = wireMockClassRule; @DynamicPropertySource static void webClientConfig(DynamicPropertyRegistry registry) { @@ -42,18 +40,21 @@ public void basicWireMockExample() { System.out.println("Stored stub mappings: " + wireMockClassRule.getStubMappings()); wireMockClassRule.stubFor( - WireMock.get("/todos") - .willReturn(aResponse() - .withHeader("Content-Type", MediaType.APPLICATION_JSON_VALUE) - .withBody("[]")) - ); + WireMock.get("/todos") + .willReturn( + aResponse() + .withHeader("Content-Type", MediaType.APPLICATION_JSON_VALUE) + .withBody("[]"))); this.webTestClient - .get() - .uri("/api/todos") - .exchange() - .expectStatus().isOk() - .expectBody().jsonPath("$.length()").isEqualTo(0); + .get() + .uri("/api/todos") + .exchange() + .expectStatus() + .isOk() + .expectBody() + .jsonPath("$.length()") + .isEqualTo(0); } @Test @@ -62,17 +63,20 @@ public void basicWireMockExampleTwo() { System.out.println("Stored stub mappings: " + wireMockClassRule.getStubMappings()); wireMockClassRule.stubFor( - WireMock.get("/todos") - .willReturn(aResponse() - .withHeader("Content-Type", MediaType.APPLICATION_JSON_VALUE) - .withBody("[]")) - ); + WireMock.get("/todos") + .willReturn( + aResponse() + .withHeader("Content-Type", MediaType.APPLICATION_JSON_VALUE) + .withBody("[]"))); this.webTestClient - .get() - .uri("/api/todos") - .exchange() - .expectStatus().isOk() - .expectBody().jsonPath("$.length()").isEqualTo(0); + .get() + .uri("/api/todos") + .exchange() + .expectStatus() + .isOk() + .expectBody() + .jsonPath("$.length()") + .isEqualTo(0); } } diff --git a/spring-boot-integration-tests-wiremock/src/test/java/de/rieckpil/blog/TodoControllerJUnit5ExtensionIT.java b/spring-boot-integration-tests-wiremock/src/test/java/de/rieckpil/blog/TodoControllerJUnit5ExtensionIT.java index 63e840d2..cbc7e727 100644 --- a/spring-boot-integration-tests-wiremock/src/test/java/de/rieckpil/blog/TodoControllerJUnit5ExtensionIT.java +++ b/spring-boot-integration-tests-wiremock/src/test/java/de/rieckpil/blog/TodoControllerJUnit5ExtensionIT.java @@ -1,5 +1,9 @@ package de.rieckpil.blog; +import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; +import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig; +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.*; + import com.github.tomakehurst.wiremock.client.WireMock; import com.github.tomakehurst.wiremock.junit5.WireMockExtension; import org.eclipse.jetty.http.HttpStatus; @@ -13,29 +17,24 @@ import org.springframework.test.context.DynamicPropertySource; import org.springframework.test.web.reactive.server.WebTestClient; -import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; -import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.*; - @SpringBootTest(webEnvironment = RANDOM_PORT) class TodoControllerJUnit5ExtensionIT { - @Autowired - private WebTestClient webTestClient; + @Autowired private WebTestClient webTestClient; @RegisterExtension - static WireMockExtension wireMockServer = WireMockExtension.newInstance() - .options(wireMockConfig().dynamicPort()) - .build(); + static WireMockExtension wireMockServer = + WireMockExtension.newInstance().options(wireMockConfig().dynamicPort()).build(); -@DynamicPropertySource -static void configureProperties(DynamicPropertyRegistry registry) { - registry.add("todo_base_url", wireMockServer::baseUrl); -} + @DynamicPropertySource + static void configureProperties(DynamicPropertyRegistry registry) { + registry.add("todo_base_url", wireMockServer::baseUrl); + } @AfterEach void resetAll() { - // we're using one WireMock server for the test class (see static on the WireMockExtension definition) + // we're using one WireMock server for the test class (see static on the WireMockExtension + // definition) wireMockServer.resetAll(); } @@ -43,34 +42,37 @@ void resetAll() { void basicWireMockExample() { wireMockServer.stubFor( - WireMock.get(WireMock.urlEqualTo("/todos")) - .willReturn(aResponse() - .withHeader("Content-Type", MediaType.APPLICATION_JSON_VALUE) - .withBodyFile("todo-api/response-200.json")) - ); + WireMock.get(WireMock.urlEqualTo("/todos")) + .willReturn( + aResponse() + .withHeader("Content-Type", MediaType.APPLICATION_JSON_VALUE) + .withBodyFile("todo-api/response-200.json"))); this.webTestClient - .get() - .uri("/api/todos") - .exchange() - .expectStatus().isOk() - .expectBody().jsonPath("$.length()").isEqualTo(3) - .jsonPath("$[0].title").isEqualTo("delectus aut autem"); + .get() + .uri("/api/todos") + .exchange() + .expectStatus() + .isOk() + .expectBody() + .jsonPath("$.length()") + .isEqualTo(3) + .jsonPath("$[0].title") + .isEqualTo("delectus aut autem"); } + @Test void testGetAllTodosShouldPropagateErrorMessageFromClient() { wireMockServer.stubFor( - WireMock.get("/todos") - .willReturn(aResponse() - .withStatus(403) - .withFixedDelay(2000)) // milliseconds - ); + WireMock.get("/todos") + .willReturn(aResponse().withStatus(403).withFixedDelay(2000)) // milliseconds + ); this.webTestClient - .get() - .uri("/api/todos") - .exchange() - .expectStatus() - .isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR_500); + .get() + .uri("/api/todos") + .exchange() + .expectStatus() + .isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR_500); } } diff --git a/spring-boot-integration-tests-wiremock/src/test/java/de/rieckpil/blog/TodoControllerJUnit5IT.java b/spring-boot-integration-tests-wiremock/src/test/java/de/rieckpil/blog/TodoControllerJUnit5IT.java index dc00581b..f1b51dd3 100644 --- a/spring-boot-integration-tests-wiremock/src/test/java/de/rieckpil/blog/TodoControllerJUnit5IT.java +++ b/spring-boot-integration-tests-wiremock/src/test/java/de/rieckpil/blog/TodoControllerJUnit5IT.java @@ -1,5 +1,7 @@ package de.rieckpil.blog; +import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; + import com.github.tomakehurst.wiremock.WireMockServer; import com.github.tomakehurst.wiremock.client.WireMock; import org.junit.jupiter.api.AfterEach; @@ -10,17 +12,13 @@ import org.springframework.test.context.ContextConfiguration; import org.springframework.test.web.reactive.server.WebTestClient; -import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; - @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @ContextConfiguration(initializers = {WireMockInitializer.class}) class TodoControllerJUnit5IT { - @Autowired - private WebTestClient webTestClient; + @Autowired private WebTestClient webTestClient; - @Autowired - private WireMockServer wireMockServer; + @Autowired private WireMockServer wireMockServer; @AfterEach void resetAll() { @@ -31,18 +29,22 @@ void resetAll() { void basicWireMockExample() { wireMockServer.stubFor( - WireMock.get(WireMock.urlEqualTo("/todos")) - .willReturn(aResponse() - .withHeader("Content-Type", MediaType.APPLICATION_JSON_VALUE) - .withBodyFile("todo-api/response-200.json")) - ); + WireMock.get(WireMock.urlEqualTo("/todos")) + .willReturn( + aResponse() + .withHeader("Content-Type", MediaType.APPLICATION_JSON_VALUE) + .withBodyFile("todo-api/response-200.json"))); this.webTestClient - .get() - .uri("/api/todos") - .exchange() - .expectStatus().isOk() - .expectBody().jsonPath("$.length()").isEqualTo(3) - .jsonPath("$[0].title").isEqualTo("delectus aut autem"); + .get() + .uri("/api/todos") + .exchange() + .expectStatus() + .isOk() + .expectBody() + .jsonPath("$.length()") + .isEqualTo(3) + .jsonPath("$[0].title") + .isEqualTo("delectus aut autem"); } } diff --git a/spring-boot-integration-tests-wiremock/src/test/java/de/rieckpil/blog/TodoControllerSpringInitializerIT.java b/spring-boot-integration-tests-wiremock/src/test/java/de/rieckpil/blog/TodoControllerSpringInitializerIT.java index b3106e3d..a351e881 100644 --- a/spring-boot-integration-tests-wiremock/src/test/java/de/rieckpil/blog/TodoControllerSpringInitializerIT.java +++ b/spring-boot-integration-tests-wiremock/src/test/java/de/rieckpil/blog/TodoControllerSpringInitializerIT.java @@ -1,5 +1,8 @@ package de.rieckpil.blog; +import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment; + import com.github.tomakehurst.wiremock.WireMockServer; import com.github.tomakehurst.wiremock.client.WireMock; import org.eclipse.jetty.http.HttpStatus; @@ -11,18 +14,13 @@ import org.springframework.test.context.ContextConfiguration; import org.springframework.test.web.reactive.server.WebTestClient; -import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment; - @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) @ContextConfiguration(initializers = {WireMockInitializer.class}) class TodoControllerSpringInitializerIT { - @Autowired - private WireMockServer wireMockServer; + @Autowired private WireMockServer wireMockServer; - @Autowired - private WebTestClient webTestClient; + @Autowired private WebTestClient webTestClient; @AfterEach public void afterEach() { @@ -32,40 +30,39 @@ public void afterEach() { @Test void testGetAllTodosShouldReturnDataFromClient() { this.wireMockServer.stubFor( - WireMock.get("/todos") - .willReturn(aResponse() - .withHeader("Content-Type", MediaType.APPLICATION_JSON_VALUE) - .withBody("[{\"userId\": 1,\"id\": 1,\"title\": \"Learn Spring Boot 3.0\", \"completed\": false}," + - "{\"userId\": 1,\"id\": 2,\"title\": \"Learn WireMock\", \"completed\": true}]")) - ); + WireMock.get("/todos") + .willReturn( + aResponse() + .withHeader("Content-Type", MediaType.APPLICATION_JSON_VALUE) + .withBody( + "[{\"userId\": 1,\"id\": 1,\"title\": \"Learn Spring Boot 3.0\", \"completed\": false}," + + "{\"userId\": 1,\"id\": 2,\"title\": \"Learn WireMock\", \"completed\": true}]"))); this.webTestClient - .get() - .uri("/api/todos") - .exchange() - .expectStatus() - .is2xxSuccessful() - .expectBody() - .jsonPath("$[0].title") - .isEqualTo("Learn Spring Boot 3.0") - .jsonPath("$.length()") - .isEqualTo(2); + .get() + .uri("/api/todos") + .exchange() + .expectStatus() + .is2xxSuccessful() + .expectBody() + .jsonPath("$[0].title") + .isEqualTo("Learn Spring Boot 3.0") + .jsonPath("$.length()") + .isEqualTo(2); } @Test void testGetAllTodosShouldPropagateErrorMessageFromClient() { this.wireMockServer.stubFor( - WireMock.get("/todos") - .willReturn(aResponse() - .withStatus(403) - .withFixedDelay(2000)) // milliseconds - ); + WireMock.get("/todos") + .willReturn(aResponse().withStatus(403).withFixedDelay(2000)) // milliseconds + ); this.webTestClient - .get() - .uri("/api/todos") - .exchange() - .expectStatus() - .isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR_500); + .get() + .uri("/api/todos") + .exchange() + .expectStatus() + .isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR_500); } } diff --git a/spring-boot-integration-tests-wiremock/src/test/java/de/rieckpil/blog/WireMockInitializer.java b/spring-boot-integration-tests-wiremock/src/test/java/de/rieckpil/blog/WireMockInitializer.java index 77041674..fa1028bd 100644 --- a/spring-boot-integration-tests-wiremock/src/test/java/de/rieckpil/blog/WireMockInitializer.java +++ b/spring-boot-integration-tests-wiremock/src/test/java/de/rieckpil/blog/WireMockInitializer.java @@ -2,35 +2,32 @@ import com.github.tomakehurst.wiremock.WireMockServer; import com.github.tomakehurst.wiremock.core.WireMockConfiguration; +import java.util.Map; import org.springframework.boot.test.util.TestPropertyValues; import org.springframework.context.ApplicationContextInitializer; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.event.ContextClosedEvent; -import java.util.Map; - -public class WireMockInitializer implements ApplicationContextInitializer { +public class WireMockInitializer + implements ApplicationContextInitializer { @Override public void initialize(ConfigurableApplicationContext applicationContext) { - WireMockServer wireMockServer = - new WireMockServer(new WireMockConfiguration().dynamicPort()); + WireMockServer wireMockServer = new WireMockServer(new WireMockConfiguration().dynamicPort()); wireMockServer.start(); - applicationContext.addApplicationListener(applicationEvent -> { - if (applicationEvent instanceof ContextClosedEvent) { - wireMockServer.stop(); - } - }); - - applicationContext.getBeanFactory() - .registerSingleton("wireMockServer", wireMockServer); + applicationContext.addApplicationListener( + applicationEvent -> { + if (applicationEvent instanceof ContextClosedEvent) { + wireMockServer.stop(); + } + }); - TestPropertyValues - .of(Map.of("todo_base_url", wireMockServer.baseUrl())) - .applyTo(applicationContext); + applicationContext.getBeanFactory().registerSingleton("wireMockServer", wireMockServer); + TestPropertyValues.of(Map.of("todo_base_url", wireMockServer.baseUrl())) + .applyTo(applicationContext); } } diff --git a/spring-boot-kotlin-testcontainers/pom.xml b/spring-boot-kotlin-testcontainers/pom.xml index b2e07a0a..765f620d 100644 --- a/spring-boot-kotlin-testcontainers/pom.xml +++ b/spring-boot-kotlin-testcontainers/pom.xml @@ -1,25 +1,19 @@ - + 4.0.0 + - org.springframework.boot - spring-boot-starter-parent - 2.3.0.RELEASE - + de.rieckpil.blog + blog-parent + 0.0.1-SNAPSHOT + ../pom.xml - de.rieckpil.blog + spring-boot-kotlin-testcontainers 0.0.1-SNAPSHOT spring-boot-kotlin-testcontainers Demo project for Spring Boot - - 11 - 1.3.72 - 1.16.0 - - org.springframework.boot @@ -66,23 +60,21 @@ - - org.testcontainers - postgresql - ${testcontainers.version} - test - - - org.testcontainers - junit-jupiter - ${testcontainers.version} - test - + + org.testcontainers + postgresql + ${testcontainers.version} + test + + + org.testcontainers + junit-jupiter + ${testcontainers.version} + test + - ${project.basedir}/src/main/kotlin - ${project.basedir}/src/test/kotlin org.springframework.boot @@ -114,6 +106,8 @@ + ${project.basedir}/src/main/kotlin + ${project.basedir}/src/test/kotlin diff --git a/spring-boot-kotlin-testcontainers/src/main/kotlin/de/rieckpil/blog/Book.kt b/spring-boot-kotlin-testcontainers/src/main/kotlin/de/rieckpil/blog/Book.kt index 2c45db39..38bbf893 100644 --- a/spring-boot-kotlin-testcontainers/src/main/kotlin/de/rieckpil/blog/Book.kt +++ b/spring-boot-kotlin-testcontainers/src/main/kotlin/de/rieckpil/blog/Book.kt @@ -1,7 +1,7 @@ package de.rieckpil.blog import org.hibernate.annotations.NaturalId -import javax.persistence.* +import jakarta.persistence.* @Entity @Table(name = "books") diff --git a/spring-boot-override-test-properties/pom.xml b/spring-boot-override-test-properties/pom.xml index ff4b0a71..4227da3f 100644 --- a/spring-boot-override-test-properties/pom.xml +++ b/spring-boot-override-test-properties/pom.xml @@ -2,22 +2,18 @@ 4.0.0 + - org.springframework.boot - spring-boot-starter-parent - 2.4.0 - + de.rieckpil.blog + blog-parent + 0.0.1-SNAPSHOT + ../pom.xml - de.rieckpil.blog spring-boot-override-test-properties 0.0.1-SNAPSHOT spring-boot-override-test-properties - - 11 - - org.springframework.boot @@ -31,7 +27,7 @@ com.github.tomakehurst - wiremock + wiremock-standalone 2.27.2 test diff --git a/spring-boot-override-test-properties/src/main/java/de/rieckpil/blog/Application.java b/spring-boot-override-test-properties/src/main/java/de/rieckpil/blog/Application.java index bd5e4c56..6511f3c1 100644 --- a/spring-boot-override-test-properties/src/main/java/de/rieckpil/blog/Application.java +++ b/spring-boot-override-test-properties/src/main/java/de/rieckpil/blog/Application.java @@ -9,5 +9,4 @@ public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } - } diff --git a/spring-boot-override-test-properties/src/main/java/de/rieckpil/blog/BadOrderService.java b/spring-boot-override-test-properties/src/main/java/de/rieckpil/blog/BadOrderService.java index 44307c4e..154ae16e 100644 --- a/spring-boot-override-test-properties/src/main/java/de/rieckpil/blog/BadOrderService.java +++ b/spring-boot-override-test-properties/src/main/java/de/rieckpil/blog/BadOrderService.java @@ -1,9 +1,8 @@ package de.rieckpil.blog; -import org.springframework.beans.factory.annotation.Value; - import java.math.BigDecimal; import java.util.Set; +import org.springframework.beans.factory.annotation.Value; public class BadOrderService { diff --git a/spring-boot-override-test-properties/src/main/java/de/rieckpil/blog/OrderService.java b/spring-boot-override-test-properties/src/main/java/de/rieckpil/blog/OrderService.java index 676938e3..5ffd9f52 100644 --- a/spring-boot-override-test-properties/src/main/java/de/rieckpil/blog/OrderService.java +++ b/spring-boot-override-test-properties/src/main/java/de/rieckpil/blog/OrderService.java @@ -1,16 +1,15 @@ package de.rieckpil.blog; -import org.springframework.beans.factory.annotation.Value; - import java.math.BigDecimal; import java.util.Set; +import org.springframework.beans.factory.annotation.Value; public class OrderService { private final Set freeShippingCountries; - public OrderService(@Value("${order.free-shipping-countries}") - Set freeShippingCountries) { + public OrderService( + @Value("${order.free-shipping-countries}") Set freeShippingCountries) { this.freeShippingCountries = freeShippingCountries; } diff --git a/spring-boot-override-test-properties/src/test/java/de/rieckpil/blog/ApplicationInitializerTest.java b/spring-boot-override-test-properties/src/test/java/de/rieckpil/blog/ApplicationInitializerTest.java index 958eb9c5..f9672480 100644 --- a/spring-boot-override-test-properties/src/test/java/de/rieckpil/blog/ApplicationInitializerTest.java +++ b/spring-boot-override-test-properties/src/test/java/de/rieckpil/blog/ApplicationInitializerTest.java @@ -1,13 +1,13 @@ package de.rieckpil.blog; +import static org.junit.jupiter.api.Assertions.assertNotNull; + import de.rieckpil.blog.initializer.WireMockInitializer; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.ContextConfiguration; -import static org.junit.jupiter.api.Assertions.assertNotNull; - @SpringBootTest @ContextConfiguration(initializers = WireMockInitializer.class) class ApplicationInitializerTest { diff --git a/spring-boot-override-test-properties/src/test/java/de/rieckpil/blog/ApplicationPropertySourceTest.java b/spring-boot-override-test-properties/src/test/java/de/rieckpil/blog/ApplicationPropertySourceTest.java index 51df0e71..1ea8856e 100644 --- a/spring-boot-override-test-properties/src/test/java/de/rieckpil/blog/ApplicationPropertySourceTest.java +++ b/spring-boot-override-test-properties/src/test/java/de/rieckpil/blog/ApplicationPropertySourceTest.java @@ -1,12 +1,12 @@ package de.rieckpil.blog; +import static org.junit.jupiter.api.Assertions.assertEquals; + import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.TestPropertySource; -import static org.junit.jupiter.api.Assertions.assertEquals; - @SpringBootTest @TestPropertySource("/custom.properties") class ApplicationPropertySourceTest { diff --git a/spring-boot-override-test-properties/src/test/java/de/rieckpil/blog/ApplicationTest.java b/spring-boot-override-test-properties/src/test/java/de/rieckpil/blog/ApplicationTest.java index 0075009a..18e6b2b7 100644 --- a/spring-boot-override-test-properties/src/test/java/de/rieckpil/blog/ApplicationTest.java +++ b/spring-boot-override-test-properties/src/test/java/de/rieckpil/blog/ApplicationTest.java @@ -1,12 +1,11 @@ package de.rieckpil.blog; +import static org.junit.jupiter.api.Assertions.assertEquals; + import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.test.autoconfigure.json.JsonTest; import org.springframework.boot.test.context.SpringBootTest; -import static org.junit.jupiter.api.Assertions.assertEquals; - @SpringBootTest(properties = "welcome.message=Spring Boot Test Hello World!") class ApplicationTest { diff --git a/spring-boot-override-test-properties/src/test/java/de/rieckpil/blog/BadOrderServiceTest.java b/spring-boot-override-test-properties/src/test/java/de/rieckpil/blog/BadOrderServiceTest.java index bf306e41..12e49996 100644 --- a/spring-boot-override-test-properties/src/test/java/de/rieckpil/blog/BadOrderServiceTest.java +++ b/spring-boot-override-test-properties/src/test/java/de/rieckpil/blog/BadOrderServiceTest.java @@ -1,12 +1,11 @@ package de.rieckpil.blog; -import org.junit.jupiter.api.Test; -import org.springframework.test.util.ReflectionTestUtils; +import static org.junit.jupiter.api.Assertions.assertEquals; import java.math.BigDecimal; import java.util.Set; - -import static org.junit.jupiter.api.Assertions.assertEquals; +import org.junit.jupiter.api.Test; +import org.springframework.test.util.ReflectionTestUtils; class BadOrderServiceTest { diff --git a/spring-boot-override-test-properties/src/test/java/de/rieckpil/blog/OrderServiceTest.java b/spring-boot-override-test-properties/src/test/java/de/rieckpil/blog/OrderServiceTest.java index d017197e..7fc82d75 100644 --- a/spring-boot-override-test-properties/src/test/java/de/rieckpil/blog/OrderServiceTest.java +++ b/spring-boot-override-test-properties/src/test/java/de/rieckpil/blog/OrderServiceTest.java @@ -1,11 +1,10 @@ package de.rieckpil.blog; -import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; import java.math.BigDecimal; import java.util.Set; - -import static org.junit.jupiter.api.Assertions.assertEquals; +import org.junit.jupiter.api.Test; class OrderServiceTest { diff --git a/spring-boot-override-test-properties/src/test/java/de/rieckpil/blog/RootControllerInlineTest.java b/spring-boot-override-test-properties/src/test/java/de/rieckpil/blog/RootControllerInlineTest.java index 5ce75c00..451b1e61 100644 --- a/spring-boot-override-test-properties/src/test/java/de/rieckpil/blog/RootControllerInlineTest.java +++ b/spring-boot-override-test-properties/src/test/java/de/rieckpil/blog/RootControllerInlineTest.java @@ -10,14 +10,13 @@ @WebMvcTest(value = RootController.class, properties = "welcome.message=Inline Hello World!") class RootControllerInlineTest { - @Autowired - private MockMvc mockMvc; + @Autowired private MockMvc mockMvc; @Test void shouldReturnDefaultWelcomeMessage() throws Exception { this.mockMvc - .perform(MockMvcRequestBuilders.get("/")) - .andExpect(MockMvcResultMatchers.status().isOk()) - .andExpect(MockMvcResultMatchers.content().string("Inline Hello World!")); + .perform(MockMvcRequestBuilders.get("/")) + .andExpect(MockMvcResultMatchers.status().isOk()) + .andExpect(MockMvcResultMatchers.content().string("Inline Hello World!")); } } diff --git a/spring-boot-override-test-properties/src/test/java/de/rieckpil/blog/RootControllerProfileTest.java b/spring-boot-override-test-properties/src/test/java/de/rieckpil/blog/RootControllerProfileTest.java index 8d78ff57..61999815 100644 --- a/spring-boot-override-test-properties/src/test/java/de/rieckpil/blog/RootControllerProfileTest.java +++ b/spring-boot-override-test-properties/src/test/java/de/rieckpil/blog/RootControllerProfileTest.java @@ -12,14 +12,13 @@ @ActiveProfiles("test") class RootControllerProfileTest { - @Autowired - private MockMvc mockMvc; + @Autowired private MockMvc mockMvc; @Test void shouldReturnDefaultWelcomeMessage() throws Exception { this.mockMvc - .perform(MockMvcRequestBuilders.get("/")) - .andExpect(MockMvcResultMatchers.status().isOk()) - .andExpect(MockMvcResultMatchers.content().string("Test Profile Hello World!")); + .perform(MockMvcRequestBuilders.get("/")) + .andExpect(MockMvcResultMatchers.status().isOk()) + .andExpect(MockMvcResultMatchers.content().string("Test Profile Hello World!")); } } diff --git a/spring-boot-override-test-properties/src/test/java/de/rieckpil/blog/RootControllerTest.java b/spring-boot-override-test-properties/src/test/java/de/rieckpil/blog/RootControllerTest.java index 657a7822..8c3543d9 100644 --- a/spring-boot-override-test-properties/src/test/java/de/rieckpil/blog/RootControllerTest.java +++ b/spring-boot-override-test-properties/src/test/java/de/rieckpil/blog/RootControllerTest.java @@ -10,14 +10,13 @@ @WebMvcTest(RootController.class) class RootControllerTest { - @Autowired - private MockMvc mockMvc; + @Autowired private MockMvc mockMvc; @Test void shouldReturnDefaultWelcomeMessage() throws Exception { this.mockMvc - .perform(MockMvcRequestBuilders.get("/")) - .andExpect(MockMvcResultMatchers.status().isOk()) - .andExpect(MockMvcResultMatchers.content().string("Test Default Profile Hello World!")); + .perform(MockMvcRequestBuilders.get("/")) + .andExpect(MockMvcResultMatchers.status().isOk()) + .andExpect(MockMvcResultMatchers.content().string("Test Default Profile Hello World!")); } } diff --git a/spring-boot-override-test-properties/src/test/java/de/rieckpil/blog/RootControllerTestPropertyTest.java b/spring-boot-override-test-properties/src/test/java/de/rieckpil/blog/RootControllerTestPropertyTest.java index 781c0d3b..f7feb1f9 100644 --- a/spring-boot-override-test-properties/src/test/java/de/rieckpil/blog/RootControllerTestPropertyTest.java +++ b/spring-boot-override-test-properties/src/test/java/de/rieckpil/blog/RootControllerTestPropertyTest.java @@ -12,14 +12,13 @@ @TestPropertySource(properties = "welcome.message=Test Property Hello World!") class RootControllerTestPropertyTest { - @Autowired - private MockMvc mockMvc; + @Autowired private MockMvc mockMvc; @Test void shouldReturnDefaultWelcomeMessage() throws Exception { this.mockMvc - .perform(MockMvcRequestBuilders.get("/")) - .andExpect(MockMvcResultMatchers.status().isOk()) - .andExpect(MockMvcResultMatchers.content().string("Test Property Hello World!")); + .perform(MockMvcRequestBuilders.get("/")) + .andExpect(MockMvcResultMatchers.status().isOk()) + .andExpect(MockMvcResultMatchers.content().string("Test Property Hello World!")); } } diff --git a/spring-boot-override-test-properties/src/test/java/de/rieckpil/blog/initializer/WireMockInitializer.java b/spring-boot-override-test-properties/src/test/java/de/rieckpil/blog/initializer/WireMockInitializer.java index 4022d87f..36ff2432 100644 --- a/spring-boot-override-test-properties/src/test/java/de/rieckpil/blog/initializer/WireMockInitializer.java +++ b/spring-boot-override-test-properties/src/test/java/de/rieckpil/blog/initializer/WireMockInitializer.java @@ -2,6 +2,7 @@ import com.github.tomakehurst.wiremock.WireMockServer; import com.github.tomakehurst.wiremock.core.WireMockConfiguration; +import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.test.util.TestPropertyValues; @@ -9,9 +10,8 @@ import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.event.ContextClosedEvent; -import java.util.Map; - -public class WireMockInitializer implements ApplicationContextInitializer { +public class WireMockInitializer + implements ApplicationContextInitializer { private static final Logger LOG = LoggerFactory.getLogger(WireMockInitializer.class); @@ -25,15 +25,16 @@ public void initialize(ConfigurableApplicationContext applicationContext) { LOG.info("WireMockServer successfully started"); - applicationContext.addApplicationListener(applicationEvent -> { - if (applicationEvent instanceof ContextClosedEvent) { - LOG.info("Stopping the WireMockServer"); - wireMockServer.stop(); - } - }); - - TestPropertyValues - .of(Map.of("clients.order-api.base-url", wireMockServer.baseUrl() + "/orders")) - .applyTo(applicationContext); + applicationContext.addApplicationListener( + applicationEvent -> { + if (applicationEvent instanceof ContextClosedEvent) { + LOG.info("Stopping the WireMockServer"); + wireMockServer.stop(); + } + }); + + TestPropertyValues.of( + Map.of("clients.order-api.base-url", wireMockServer.baseUrl() + "/orders")) + .applyTo(applicationContext); } } diff --git a/spring-boot-rest-assured/src/main/java/de/rieckpil/blog/Application.java b/spring-boot-rest-assured/src/main/java/de/rieckpil/blog/Application.java index bd5e4c56..6511f3c1 100644 --- a/spring-boot-rest-assured/src/main/java/de/rieckpil/blog/Application.java +++ b/spring-boot-rest-assured/src/main/java/de/rieckpil/blog/Application.java @@ -9,5 +9,4 @@ public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } - } diff --git a/spring-boot-rest-assured/src/main/java/de/rieckpil/blog/Book.java b/spring-boot-rest-assured/src/main/java/de/rieckpil/blog/Book.java index 9a22a511..44075502 100644 --- a/spring-boot-rest-assured/src/main/java/de/rieckpil/blog/Book.java +++ b/spring-boot-rest-assured/src/main/java/de/rieckpil/blog/Book.java @@ -7,8 +7,7 @@ public class Book { private String title; private String author; - public Book() { - } + public Book() {} public Book(Long id, String isbn, String title, String author) { this.id = id; diff --git a/spring-boot-rest-assured/src/main/java/de/rieckpil/blog/BookController.java b/spring-boot-rest-assured/src/main/java/de/rieckpil/blog/BookController.java index 843bdfff..55935f96 100644 --- a/spring-boot-rest-assured/src/main/java/de/rieckpil/blog/BookController.java +++ b/spring-boot-rest-assured/src/main/java/de/rieckpil/blog/BookController.java @@ -1,5 +1,7 @@ package de.rieckpil.blog; +import jakarta.validation.Valid; +import java.util.List; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -7,10 +9,6 @@ import org.springframework.web.util.UriComponents; import org.springframework.web.util.UriComponentsBuilder; -import jakarta.annotation.security.RolesAllowed; -import jakarta.validation.Valid; -import java.util.List; - @RestController @RequestMapping("/api/books") public class BookController { @@ -33,12 +31,12 @@ public ResponseEntity getBookById(@PathVariable("id") Long id) { @PostMapping public ResponseEntity createNewBook( - @Valid @RequestBody BookRequest bookRequest, - UriComponentsBuilder uriComponentsBuilder) { + @Valid @RequestBody BookRequest bookRequest, UriComponentsBuilder uriComponentsBuilder) { Long bookId = bookService.createNewBook(bookRequest); - UriComponents uriComponents = uriComponentsBuilder.path("/api/books/{id}").buildAndExpand(bookId); + UriComponents uriComponents = + uriComponentsBuilder.path("/api/books/{id}").buildAndExpand(bookId); HttpHeaders headers = new HttpHeaders(); headers.setLocation(uriComponents.toUri()); diff --git a/spring-boot-rest-assured/src/main/java/de/rieckpil/blog/BookRequest.java b/spring-boot-rest-assured/src/main/java/de/rieckpil/blog/BookRequest.java index 1bc3c81c..341fb3a9 100644 --- a/spring-boot-rest-assured/src/main/java/de/rieckpil/blog/BookRequest.java +++ b/spring-boot-rest-assured/src/main/java/de/rieckpil/blog/BookRequest.java @@ -1,19 +1,17 @@ package de.rieckpil.blog; - import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.Size; + public class BookRequest { - @NotEmpty - private String title; + @NotEmpty private String title; @NotEmpty @Size(max = 20) private String isbn; - @NotEmpty - private String author; + @NotEmpty private String author; public String getTitle() { return title; diff --git a/spring-boot-rest-assured/src/main/java/de/rieckpil/blog/BookService.java b/spring-boot-rest-assured/src/main/java/de/rieckpil/blog/BookService.java index 7376d7d6..be0d871b 100644 --- a/spring-boot-rest-assured/src/main/java/de/rieckpil/blog/BookService.java +++ b/spring-boot-rest-assured/src/main/java/de/rieckpil/blog/BookService.java @@ -1,10 +1,9 @@ package de.rieckpil.blog; -import org.springframework.stereotype.Service; - import java.util.ArrayList; import java.util.List; import java.util.concurrent.ThreadLocalRandom; +import org.springframework.stereotype.Service; @Service public class BookService { @@ -34,10 +33,10 @@ public List getAllBooks(int amount) { } public Book getBookById(Long id) { - return this.bookStore - .stream() - .filter(book -> book.getId().equals(id)) - .findFirst() - .orElseThrow(() -> new BookNotFoundException(String.format("Book with id: '%s' not found", id))); + return this.bookStore.stream() + .filter(book -> book.getId().equals(id)) + .findFirst() + .orElseThrow( + () -> new BookNotFoundException(String.format("Book with id: '%s' not found", id))); } } diff --git a/spring-boot-rest-assured/src/main/java/de/rieckpil/blog/WebSecurityConfig.java b/spring-boot-rest-assured/src/main/java/de/rieckpil/blog/WebSecurityConfig.java index dec8ac19..9f64ad95 100644 --- a/spring-boot-rest-assured/src/main/java/de/rieckpil/blog/WebSecurityConfig.java +++ b/spring-boot-rest-assured/src/main/java/de/rieckpil/blog/WebSecurityConfig.java @@ -13,15 +13,19 @@ public class WebSecurityConfig { @Bean public SecurityFilterChain configure(HttpSecurity http) throws Exception { - http - .csrf(AbstractHttpConfigurer::disable) - .httpBasic(Customizer.withDefaults()) - .authorizeHttpRequests( - requests -> requests - .requestMatchers(HttpMethod.GET, "/api/books").permitAll() - .requestMatchers(HttpMethod.GET, "/api/books/*").permitAll() - .requestMatchers(HttpMethod.POST, "/api/books").hasRole("ADMIN") - .anyRequest().authenticated()); + http.csrf(AbstractHttpConfigurer::disable) + .httpBasic(Customizer.withDefaults()) + .authorizeHttpRequests( + requests -> + requests + .requestMatchers(HttpMethod.GET, "/api/books") + .permitAll() + .requestMatchers(HttpMethod.GET, "/api/books/*") + .permitAll() + .requestMatchers(HttpMethod.POST, "/api/books") + .hasRole("ADMIN") + .anyRequest() + .authenticated()); return http.build(); } diff --git a/spring-boot-rest-assured/src/test/java/de/rieckpil/blog/ApplicationTest.java b/spring-boot-rest-assured/src/test/java/de/rieckpil/blog/ApplicationTest.java index 686ee378..83d7e80d 100644 --- a/spring-boot-rest-assured/src/test/java/de/rieckpil/blog/ApplicationTest.java +++ b/spring-boot-rest-assured/src/test/java/de/rieckpil/blog/ApplicationTest.java @@ -1,5 +1,7 @@ package de.rieckpil.blog; +import static org.springframework.boot.test.context.SpringBootTest.*; + import io.restassured.RestAssured; import io.restassured.filter.log.RequestLoggingFilter; import io.restassured.response.ExtractableResponse; @@ -9,39 +11,38 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.server.LocalServerPort; -import static org.springframework.boot.test.context.SpringBootTest.*; - @SpringBootTest( - webEnvironment = WebEnvironment.RANDOM_PORT, - properties = { - "spring.security.user.name=duke", - "spring.security.user.password=secret", - "spring.security.user.roles=ADMIN" -}) + webEnvironment = WebEnvironment.RANDOM_PORT, + properties = { + "spring.security.user.name=duke", + "spring.security.user.password=secret", + "spring.security.user.roles=ADMIN" + }) class ApplicationTest { - @LocalServerPort - private Integer port; + @LocalServerPort private Integer port; @Test void shouldCreateBook() { - ExtractableResponse response = RestAssured - .given() - .filter(new RequestLoggingFilter()) - .auth().preemptive().basic("duke", "secret") - .contentType("application/json") - .body("{\"title\": \"Effective Java\", \"isbn\":\"978-0-13-468599-1\", \"author\":\"Joshua Bloch\"}") - .when() - .post("http://localhost:" + port + "/api/books") - .then() - .statusCode(201) - .extract(); + ExtractableResponse response = + RestAssured.given() + .filter(new RequestLoggingFilter()) + .auth() + .preemptive() + .basic("duke", "secret") + .contentType("application/json") + .body( + "{\"title\": \"Effective Java\", \"isbn\":\"978-0-13-468599-1\", \"author\":\"Joshua Bloch\"}") + .when() + .post("http://localhost:" + port + "/api/books") + .then() + .statusCode(201) + .extract(); - RestAssured - .when() + RestAssured.when() .get(response.header("Location")) - .then() + .then() .statusCode(200) .body("id", Matchers.notNullValue()) .body("isbn", Matchers.equalTo("978-0-13-468599-1")) diff --git a/spring-boot-rest-assured/src/test/java/de/rieckpil/blog/BookControllerTest.java b/spring-boot-rest-assured/src/test/java/de/rieckpil/blog/BookControllerTest.java index b93d56ec..be0c502e 100644 --- a/spring-boot-rest-assured/src/test/java/de/rieckpil/blog/BookControllerTest.java +++ b/spring-boot-rest-assured/src/test/java/de/rieckpil/blog/BookControllerTest.java @@ -1,6 +1,10 @@ package de.rieckpil.blog; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; + import io.restassured.module.mockmvc.RestAssuredMockMvc; +import java.util.List; import org.hamcrest.Matchers; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -13,20 +17,13 @@ import org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors; import org.springframework.test.web.servlet.MockMvc; -import java.util.List; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyInt; - @Import(WebSecurityConfig.class) @WebMvcTest(BookController.class) class BookControllerTest { - @MockBean - private BookService bookService; + @MockBean private BookService bookService; - @Autowired - private MockMvc mockMvc; + @Autowired private MockMvc mockMvc; @BeforeEach void setUp() { @@ -36,16 +33,16 @@ void setUp() { @Test void shouldAllowBookRetrievalWithoutAuthentication() { - Mockito.when(bookService.getAllBooks(42)).thenReturn( - List.of(new Book(42L, "42", "REST Assured With Spring Boot", "Duke"))); + Mockito.when(bookService.getAllBooks(42)) + .thenReturn(List.of(new Book(42L, "42", "REST Assured With Spring Boot", "Duke"))); - RestAssuredMockMvc - .given() - .auth().none() + RestAssuredMockMvc.given() + .auth() + .none() .param("amount", 42) - .when() + .when() .get("/api/books") - .then() + .then() .statusCode(200) .body("$.size()", Matchers.equalTo(1)) .body("[0].id", Matchers.equalTo(42)) @@ -57,13 +54,12 @@ void shouldAllowBookRetrievalWithoutAuthentication() { @Test void shouldAllowBookRetrievalWithoutAuthenticationShort() { - Mockito.when(bookService.getAllBooks(anyInt())).thenReturn( - List.of(new Book(42L, "42", "REST Assured With Spring Boot", "Duke"))); + Mockito.when(bookService.getAllBooks(anyInt())) + .thenReturn(List.of(new Book(42L, "42", "REST Assured With Spring Boot", "Duke"))); - RestAssuredMockMvc - .when() + RestAssuredMockMvc.when() .get("/api/books") - .then() + .then() .statusCode(200) .body("$.size()", Matchers.equalTo(1)) .body("[0].id", Matchers.equalTo(42)) @@ -77,29 +73,32 @@ void shouldAllowBookCreationForAuthenticatedAdminUsers() { Mockito.when(bookService.createNewBook(any(BookRequest.class))).thenReturn(42L); - RestAssuredMockMvc - .given() - .auth().with(SecurityMockMvcRequestPostProcessors.user("duke").roles("ADMIN")) + RestAssuredMockMvc.given() + .auth() + .with(SecurityMockMvcRequestPostProcessors.user("duke").roles("ADMIN")) .contentType("application/json") - .body("{\"title\": \"Effective Java\", \"isbn\":\"978-0-13-468599-1 \", \"author\":\"Joshua Bloch\"}") - .when() + .body( + "{\"title\": \"Effective Java\", \"isbn\":\"978-0-13-468599-1 \", \"author\":\"Joshua Bloch\"}") + .when() .post("/api/books") - .then() + .then() .statusCode(201) .header("Location", Matchers.containsString("/api/books/42")); } @Test - @WithMockUser(username = "duke", roles = {"USER", "EDITOR"}) + @WithMockUser( + username = "duke", + roles = {"USER", "EDITOR"}) void shouldBlockBookCreationForNonAdminUsers() { - RestAssuredMockMvc - .given() + RestAssuredMockMvc.given() .contentType("application/json") - .body("{\"title\": \"Effective Java\", \"isbn\":\"978-0-13-468599-1 \", \"author\":\"Joshua Bloch\"}") - .when() + .body( + "{\"title\": \"Effective Java\", \"isbn\":\"978-0-13-468599-1 \", \"author\":\"Joshua Bloch\"}") + .when() .post("/api/books") - .then() + .then() .statusCode(403); } } diff --git a/spring-boot-selenium-integration-tests/pom.xml b/spring-boot-selenium-integration-tests/pom.xml index edd62260..2ed767a5 100644 --- a/spring-boot-selenium-integration-tests/pom.xml +++ b/spring-boot-selenium-integration-tests/pom.xml @@ -4,36 +4,17 @@ 4.0.0 - org.springframework.boot - spring-boot-starter-parent - 2.5.0 - + de.rieckpil.blog + blog-parent + 0.0.1-SNAPSHOT + ../pom.xml - de.rieckpil.blog spring-boot-selenium-integration-tests 0.0.1-SNAPSHOT spring-boot-selenium-integration-tests Spring Boot Integration Test with Selenium - - 11 - 1.16.2 - 3.141.59 - - - - - - org.testcontainers - testcontainers-bom - ${testcontainers.version} - pom - import - - - - org.springframework.boot diff --git a/spring-boot-selenium-integration-tests/src/main/java/de/rieckpil/blog/Application.java b/spring-boot-selenium-integration-tests/src/main/java/de/rieckpil/blog/Application.java index bd5e4c56..6511f3c1 100644 --- a/spring-boot-selenium-integration-tests/src/main/java/de/rieckpil/blog/Application.java +++ b/spring-boot-selenium-integration-tests/src/main/java/de/rieckpil/blog/Application.java @@ -9,5 +9,4 @@ public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } - } diff --git a/spring-boot-selenium-integration-tests/src/test/java/de/rieckpil/blog/ApplicationTest.java b/spring-boot-selenium-integration-tests/src/test/java/de/rieckpil/blog/ApplicationTest.java index 24eea4ab..b6751e0d 100644 --- a/spring-boot-selenium-integration-tests/src/test/java/de/rieckpil/blog/ApplicationTest.java +++ b/spring-boot-selenium-integration-tests/src/test/java/de/rieckpil/blog/ApplicationTest.java @@ -7,7 +7,5 @@ class ApplicationTest { @Test - void contextLoads() { - } - + void contextLoads() {} } diff --git a/spring-boot-selenium-integration-tests/src/test/java/de/rieckpil/blog/IndexControllerIT.java b/spring-boot-selenium-integration-tests/src/test/java/de/rieckpil/blog/IndexControllerIT.java index c84f1943..6e7fe8ab 100644 --- a/spring-boot-selenium-integration-tests/src/test/java/de/rieckpil/blog/IndexControllerIT.java +++ b/spring-boot-selenium-integration-tests/src/test/java/de/rieckpil/blog/IndexControllerIT.java @@ -1,28 +1,28 @@ package de.rieckpil.blog; +import static org.junit.jupiter.api.Assertions.assertEquals; + import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.openqa.selenium.By; import org.openqa.selenium.WebElement; import org.openqa.selenium.chrome.ChromeOptions; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.core.env.Environment; import org.testcontainers.Testcontainers; import org.testcontainers.containers.BrowserWebDriverContainer; -import static org.junit.jupiter.api.Assertions.assertEquals; - @ExtendWith({ScreenshotOnFailureExtension.class}) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) class IndexControllerIT { - static BrowserWebDriverContainer container = new BrowserWebDriverContainer<>() - .withCapabilities(new ChromeOptions()); + static BrowserWebDriverContainer container = + new BrowserWebDriverContainer<>().withCapabilities(new ChromeOptions()); - @LocalServerPort - private int port; + @LocalServerPort private int port; @BeforeAll static void beforeAll(@Autowired Environment environment) { @@ -33,10 +33,10 @@ static void beforeAll(@Autowired Environment environment) { @Test void shouldDisplayMessage() { container - .getWebDriver() - .get(String.format("http://host.testcontainers.internal:%d/index", port)); + .getWebDriver() + .get(String.format("http://host.testcontainers.internal:%d/index", port)); - WebElement messageElement = container.getWebDriver().findElementById("message"); + WebElement messageElement = container.getWebDriver().findElement(By.id("message")); assertEquals("Integration Test with Selenium", messageElement.getText()); } diff --git a/spring-boot-selenium-integration-tests/src/test/java/de/rieckpil/blog/ScreenshotOnFailureExtension.java b/spring-boot-selenium-integration-tests/src/test/java/de/rieckpil/blog/ScreenshotOnFailureExtension.java index 2d1799e6..626e5069 100644 --- a/spring-boot-selenium-integration-tests/src/test/java/de/rieckpil/blog/ScreenshotOnFailureExtension.java +++ b/spring-boot-selenium-integration-tests/src/test/java/de/rieckpil/blog/ScreenshotOnFailureExtension.java @@ -1,16 +1,15 @@ package de.rieckpil.blog; -import org.junit.jupiter.api.extension.AfterEachCallback; -import org.junit.jupiter.api.extension.ExtensionContext; -import org.openqa.selenium.OutputType; -import org.testcontainers.containers.BrowserWebDriverContainer; - import java.io.IOException; import java.lang.reflect.Field; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.time.LocalDateTime; +import org.junit.jupiter.api.extension.AfterEachCallback; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.openqa.selenium.OutputType; +import org.testcontainers.containers.BrowserWebDriverContainer; public class ScreenshotOnFailureExtension implements AfterEachCallback { @@ -20,16 +19,19 @@ public void afterEach(ExtensionContext extensionContext) throws Exception { Object testInstance = extensionContext.getRequiredTestInstance(); Field containerField = testInstance.getClass().getDeclaredField("container"); containerField.setAccessible(true); - BrowserWebDriverContainer browserContainer = (BrowserWebDriverContainer) containerField.get(testInstance); + BrowserWebDriverContainer browserContainer = + (BrowserWebDriverContainer) containerField.get(testInstance); byte[] screenshot = browserContainer.getWebDriver().getScreenshotAs(OutputType.BYTES); try { - Path path = Paths - .get("target/selenium-screenshots") - .resolve(String.format("%s-%s-%s.png", - LocalDateTime.now(), - extensionContext.getRequiredTestClass().getName(), - extensionContext.getRequiredTestMethod().getName())); + Path path = + Paths.get("target/selenium-screenshots") + .resolve( + String.format( + "%s-%s-%s.png", + LocalDateTime.now(), + extensionContext.getRequiredTestClass().getName(), + extensionContext.getRequiredTestMethod().getName())); Files.createDirectories(path.getParent()); Files.write(path, screenshot); diff --git a/spring-boot-shedlock/pom.xml b/spring-boot-shedlock/pom.xml index 90e5af98..e4d1d909 100644 --- a/spring-boot-shedlock/pom.xml +++ b/spring-boot-shedlock/pom.xml @@ -2,22 +2,20 @@ 4.0.0 + - org.springframework.boot - spring-boot-starter-parent - 2.5.5 - + de.rieckpil.blog + blog-parent + 0.0.1-SNAPSHOT + ../pom.xml - de.rieckpil.blog spring-boot-shedlock 0.0.1-SNAPSHOT spring-boot-shedlock Demo project for Spring Boot - 11 - 1.16.0 4.29.0 @@ -68,18 +66,6 @@ - - - - org.testcontainers - testcontainers-bom - ${testcontainers.version} - pom - import - - - - diff --git a/spring-boot-shedlock/src/main/java/de/rieckpil/blog/Application.java b/spring-boot-shedlock/src/main/java/de/rieckpil/blog/Application.java index bd5e4c56..6511f3c1 100644 --- a/spring-boot-shedlock/src/main/java/de/rieckpil/blog/Application.java +++ b/spring-boot-shedlock/src/main/java/de/rieckpil/blog/Application.java @@ -9,5 +9,4 @@ public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } - } diff --git a/spring-boot-shedlock/src/main/java/de/rieckpil/blog/ShedLockConfig.java b/spring-boot-shedlock/src/main/java/de/rieckpil/blog/ShedLockConfig.java index 3a79ec15..5f6a972e 100644 --- a/spring-boot-shedlock/src/main/java/de/rieckpil/blog/ShedLockConfig.java +++ b/spring-boot-shedlock/src/main/java/de/rieckpil/blog/ShedLockConfig.java @@ -1,5 +1,6 @@ package de.rieckpil.blog; +import javax.sql.DataSource; import net.javacrumbs.shedlock.core.LockProvider; import net.javacrumbs.shedlock.provider.jdbctemplate.JdbcTemplateLockProvider; import net.javacrumbs.shedlock.spring.annotation.EnableSchedulerLock; @@ -8,8 +9,6 @@ import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.scheduling.annotation.EnableScheduling; -import javax.sql.DataSource; - @Configuration @EnableScheduling @EnableSchedulerLock(defaultLockAtMostFor = "15m") @@ -18,11 +17,9 @@ public class ShedLockConfig { @Bean public LockProvider lockProvider(DataSource dataSource) { return new JdbcTemplateLockProvider( - JdbcTemplateLockProvider.Configuration.builder() - .withJdbcTemplate(new JdbcTemplate(dataSource)) - .usingDbTime() - .build() - ); + JdbcTemplateLockProvider.Configuration.builder() + .withJdbcTemplate(new JdbcTemplate(dataSource)) + .usingDbTime() + .build()); } } - diff --git a/spring-boot-shedlock/src/test/java/de/rieckpil/blog/ApplicationTest.java b/spring-boot-shedlock/src/test/java/de/rieckpil/blog/ApplicationTest.java index e31a836d..bba66a29 100644 --- a/spring-boot-shedlock/src/test/java/de/rieckpil/blog/ApplicationTest.java +++ b/spring-boot-shedlock/src/test/java/de/rieckpil/blog/ApplicationTest.java @@ -13,10 +13,11 @@ class ApplicationTest { @Container - static PostgreSQLContainer database = new PostgreSQLContainer<>("postgres:12") - .withUsername("spring") - .withPassword("secret") - .withDatabaseName("spring"); + static PostgreSQLContainer database = + new PostgreSQLContainer<>("postgres:12") + .withUsername("spring") + .withPassword("secret") + .withDatabaseName("spring"); @DynamicPropertySource static void setProperties(DynamicPropertyRegistry registry) { @@ -26,7 +27,5 @@ static void setProperties(DynamicPropertyRegistry registry) { } @Test - void contextLoads() { - } - + void contextLoads() {} } diff --git a/spring-boot-test-mail-sending/pom.xml b/spring-boot-test-mail-sending/pom.xml index 0cf5f577..d58e8559 100644 --- a/spring-boot-test-mail-sending/pom.xml +++ b/spring-boot-test-mail-sending/pom.xml @@ -4,22 +4,18 @@ 4.0.0 - org.springframework.boot - spring-boot-starter-parent - 2.5.5 - + de.rieckpil.blog + blog-parent + 0.0.1-SNAPSHOT + ../pom.xml - de.rieckpil.blog spring-boot-test-mail-sending 0.0.1-SNAPSHOT spring-boot-test-mail-sending - 11 1.6.5 - 1.16.3 - 4.0.3 @@ -51,7 +47,6 @@ org.awaitility awaitility - ${awaitility.version} test @@ -63,25 +58,6 @@ - - - org.springframework.boot - spring-boot-maven-plugin - - - org.apache.maven.plugins - maven-failsafe-plugin - 3.0.0-M5 - - - - integration-test - verify - - - - - diff --git a/spring-boot-test-mail-sending/src/main/java/de/rieckpil/blog/Application.java b/spring-boot-test-mail-sending/src/main/java/de/rieckpil/blog/Application.java index bd5e4c56..6511f3c1 100644 --- a/spring-boot-test-mail-sending/src/main/java/de/rieckpil/blog/Application.java +++ b/spring-boot-test-mail-sending/src/main/java/de/rieckpil/blog/Application.java @@ -9,5 +9,4 @@ public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } - } diff --git a/spring-boot-test-mail-sending/src/main/java/de/rieckpil/blog/NotificationController.java b/spring-boot-test-mail-sending/src/main/java/de/rieckpil/blog/NotificationController.java index c6b5d54d..03fe5b07 100644 --- a/spring-boot-test-mail-sending/src/main/java/de/rieckpil/blog/NotificationController.java +++ b/spring-boot-test-mail-sending/src/main/java/de/rieckpil/blog/NotificationController.java @@ -1,12 +1,11 @@ package de.rieckpil.blog; +import jakarta.validation.Valid; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import javax.validation.Valid; - @RestController @RequestMapping("/notifications") public class NotificationController { diff --git a/spring-boot-test-mail-sending/src/main/java/de/rieckpil/blog/NotificationRequest.java b/spring-boot-test-mail-sending/src/main/java/de/rieckpil/blog/NotificationRequest.java index 023dd3d3..83607fce 100644 --- a/spring-boot-test-mail-sending/src/main/java/de/rieckpil/blog/NotificationRequest.java +++ b/spring-boot-test-mail-sending/src/main/java/de/rieckpil/blog/NotificationRequest.java @@ -1,15 +1,13 @@ package de.rieckpil.blog; -import javax.validation.constraints.Email; -import javax.validation.constraints.NotBlank; +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.NotBlank; public class NotificationRequest { - @Email - private String email; + @Email private String email; - @NotBlank - private String content; + @NotBlank private String content; public String getEmail() { return email; diff --git a/spring-boot-test-mail-sending/src/test/java/de/rieckpil/blog/JavaMailSenderIT.java b/spring-boot-test-mail-sending/src/test/java/de/rieckpil/blog/JavaMailSenderIT.java index 3e66372b..6e3df7d3 100644 --- a/spring-boot-test-mail-sending/src/test/java/de/rieckpil/blog/JavaMailSenderIT.java +++ b/spring-boot-test-mail-sending/src/test/java/de/rieckpil/blog/JavaMailSenderIT.java @@ -1,37 +1,31 @@ package de.rieckpil.blog; -import javax.mail.internet.MimeMessage; +import static java.util.concurrent.TimeUnit.SECONDS; +import static org.awaitility.Awaitility.await; +import static org.junit.jupiter.api.Assertions.assertEquals; import com.icegreen.greenmail.configuration.GreenMailConfiguration; import com.icegreen.greenmail.junit5.GreenMailExtension; import com.icegreen.greenmail.util.GreenMailUtil; import com.icegreen.greenmail.util.ServerSetupTest; +import javax.mail.internet.MimeMessage; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; import org.springframework.mail.SimpleMailMessage; import org.springframework.mail.javamail.JavaMailSender; -import static java.util.concurrent.TimeUnit.SECONDS; -import static org.awaitility.Awaitility.await; -import static org.junit.jupiter.api.Assertions.assertEquals; - @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) class JavaMailSenderIT { @RegisterExtension - static GreenMailExtension greenMail = new GreenMailExtension(ServerSetupTest.SMTP) - .withConfiguration(GreenMailConfiguration.aConfig().withUser("duke", "springboot")) - .withPerMethodLifecycle(false); + static GreenMailExtension greenMail = + new GreenMailExtension(ServerSetupTest.SMTP) + .withConfiguration(GreenMailConfiguration.aConfig().withUser("duke", "springboot")) + .withPerMethodLifecycle(false); - @Autowired - private JavaMailSender javaMailSender; + @Autowired private JavaMailSender javaMailSender; @Test void shouldUseGreenMail() { @@ -45,14 +39,17 @@ void shouldUseGreenMail() { javaMailSender.send(mail); // awaitility - await().atMost(2, SECONDS).untilAsserted(() -> { - MimeMessage[] receivedMessages = greenMail.getReceivedMessages(); - assertEquals(1, receivedMessages.length); - - MimeMessage receivedMessage = receivedMessages[0]; - assertEquals("Hello GreenMail!", GreenMailUtil.getBody(receivedMessage)); - assertEquals(1, receivedMessage.getAllRecipients().length); - assertEquals("test@greenmail.io", receivedMessage.getAllRecipients()[0].toString()); - }); + await() + .atMost(2, SECONDS) + .untilAsserted( + () -> { + MimeMessage[] receivedMessages = greenMail.getReceivedMessages(); + assertEquals(1, receivedMessages.length); + + MimeMessage receivedMessage = receivedMessages[0]; + assertEquals("Hello GreenMail!", GreenMailUtil.getBody(receivedMessage)); + assertEquals(1, receivedMessage.getAllRecipients().length); + assertEquals("test@greenmail.io", receivedMessage.getAllRecipients()[0].toString()); + }); } } diff --git a/spring-boot-test-mail-sending/src/test/java/de/rieckpil/blog/JavaMailSenderPerMethodIT.java b/spring-boot-test-mail-sending/src/test/java/de/rieckpil/blog/JavaMailSenderPerMethodIT.java index 2d240604..7217ede1 100644 --- a/spring-boot-test-mail-sending/src/test/java/de/rieckpil/blog/JavaMailSenderPerMethodIT.java +++ b/spring-boot-test-mail-sending/src/test/java/de/rieckpil/blog/JavaMailSenderPerMethodIT.java @@ -1,11 +1,14 @@ package de.rieckpil.blog; -import javax.mail.internet.MimeMessage; +import static java.util.concurrent.TimeUnit.SECONDS; +import static org.awaitility.Awaitility.await; +import static org.junit.jupiter.api.Assertions.assertEquals; import com.icegreen.greenmail.configuration.GreenMailConfiguration; import com.icegreen.greenmail.junit5.GreenMailExtension; import com.icegreen.greenmail.util.GreenMailUtil; import com.icegreen.greenmail.util.ServerSetupTest; +import javax.mail.internet.MimeMessage; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.springframework.beans.factory.annotation.Autowired; @@ -13,20 +16,16 @@ import org.springframework.mail.SimpleMailMessage; import org.springframework.mail.javamail.JavaMailSender; -import static java.util.concurrent.TimeUnit.SECONDS; -import static org.awaitility.Awaitility.await; -import static org.junit.jupiter.api.Assertions.assertEquals; - @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) class JavaMailSenderPerMethodIT { @RegisterExtension - static GreenMailExtension greenMail = new GreenMailExtension(ServerSetupTest.SMTP) - .withConfiguration(GreenMailConfiguration.aConfig().withUser("duke", "springboot")) - .withPerMethodLifecycle(true); + static GreenMailExtension greenMail = + new GreenMailExtension(ServerSetupTest.SMTP) + .withConfiguration(GreenMailConfiguration.aConfig().withUser("duke", "springboot")) + .withPerMethodLifecycle(true); - @Autowired - private JavaMailSender javaMailSender; + @Autowired private JavaMailSender javaMailSender; @Test void verifyDeliveryToGreenMailServer() { @@ -48,14 +47,17 @@ private void sendEmailAndVerify() { javaMailSender.send(mail); // awaitility - await().atMost(2, SECONDS).untilAsserted(() -> { - MimeMessage[] receivedMessages = greenMail.getReceivedMessages(); - assertEquals(1, receivedMessages.length); - - MimeMessage receivedMessage = receivedMessages[0]; - assertEquals("Hello GreenMail!", GreenMailUtil.getBody(receivedMessage)); - assertEquals(1, receivedMessage.getAllRecipients().length); - assertEquals("test@greenmail.io", receivedMessage.getAllRecipients()[0].toString()); - }); + await() + .atMost(2, SECONDS) + .untilAsserted( + () -> { + MimeMessage[] receivedMessages = greenMail.getReceivedMessages(); + assertEquals(1, receivedMessages.length); + + MimeMessage receivedMessage = receivedMessages[0]; + assertEquals("Hello GreenMail!", GreenMailUtil.getBody(receivedMessage)); + assertEquals(1, receivedMessage.getAllRecipients().length); + assertEquals("test@greenmail.io", receivedMessage.getAllRecipients()[0].toString()); + }); } } diff --git a/spring-boot-test-mail-sending/src/test/java/de/rieckpil/blog/NotificationControllerIT.java b/spring-boot-test-mail-sending/src/test/java/de/rieckpil/blog/NotificationControllerIT.java index 8b8cff6a..f3576b5e 100644 --- a/spring-boot-test-mail-sending/src/test/java/de/rieckpil/blog/NotificationControllerIT.java +++ b/spring-boot-test-mail-sending/src/test/java/de/rieckpil/blog/NotificationControllerIT.java @@ -1,9 +1,14 @@ package de.rieckpil.blog; +import static java.util.concurrent.TimeUnit.SECONDS; +import static org.awaitility.Awaitility.await; +import static org.junit.jupiter.api.Assertions.assertEquals; + import com.icegreen.greenmail.configuration.GreenMailConfiguration; import com.icegreen.greenmail.junit5.GreenMailExtension; import com.icegreen.greenmail.util.GreenMailUtil; import com.icegreen.greenmail.util.ServerSetupTest; +import javax.mail.internet.MimeMessage; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.springframework.beans.factory.annotation.Autowired; @@ -14,22 +19,16 @@ import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; -import javax.mail.internet.MimeMessage; - -import static java.util.concurrent.TimeUnit.SECONDS; -import static org.awaitility.Awaitility.await; -import static org.junit.jupiter.api.Assertions.assertEquals; - @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) class NotificationControllerIT { @RegisterExtension - static GreenMailExtension greenMail = new GreenMailExtension(ServerSetupTest.SMTP) - .withConfiguration(GreenMailConfiguration.aConfig().withUser("duke", "springboot")) - .withPerMethodLifecycle(false); + static GreenMailExtension greenMail = + new GreenMailExtension(ServerSetupTest.SMTP) + .withConfiguration(GreenMailConfiguration.aConfig().withUser("duke", "springboot")) + .withPerMethodLifecycle(false); - @Autowired - private TestRestTemplate testRestTemplate; + @Autowired private TestRestTemplate testRestTemplate; @Test void shouldSendEmailWithCorrectPayloadToUser() throws Exception { @@ -40,18 +39,22 @@ void shouldSendEmailWithCorrectPayloadToUser() throws Exception { headers.setContentType(MediaType.APPLICATION_JSON); HttpEntity request = new HttpEntity<>(payload, headers); - ResponseEntity response = this.testRestTemplate.postForEntity("/notifications", request, Void.class); + ResponseEntity response = + this.testRestTemplate.postForEntity("/notifications", request, Void.class); assertEquals(200, response.getStatusCodeValue()); - await().atMost(2, SECONDS).untilAsserted(() -> { - MimeMessage[] receivedMessages = greenMail.getReceivedMessages(); - assertEquals(1, receivedMessages.length); - - MimeMessage receivedMessage = receivedMessages[0]; - assertEquals("Hello World!", GreenMailUtil.getBody(receivedMessage)); - assertEquals(1, receivedMessage.getAllRecipients().length); - assertEquals("duke@spring.io", receivedMessage.getAllRecipients()[0].toString()); - }); + await() + .atMost(2, SECONDS) + .untilAsserted( + () -> { + MimeMessage[] receivedMessages = greenMail.getReceivedMessages(); + assertEquals(1, receivedMessages.length); + + MimeMessage receivedMessage = receivedMessages[0]; + assertEquals("Hello World!", GreenMailUtil.getBody(receivedMessage)); + assertEquals(1, receivedMessage.getAllRecipients().length); + assertEquals("duke@spring.io", receivedMessage.getAllRecipients()[0].toString()); + }); } } diff --git a/spring-boot-test-mail-sending/src/test/java/de/rieckpil/blog/NotificationControllerSecondIT.java b/spring-boot-test-mail-sending/src/test/java/de/rieckpil/blog/NotificationControllerSecondIT.java index f5255ded..7c0c1f7d 100644 --- a/spring-boot-test-mail-sending/src/test/java/de/rieckpil/blog/NotificationControllerSecondIT.java +++ b/spring-boot-test-mail-sending/src/test/java/de/rieckpil/blog/NotificationControllerSecondIT.java @@ -1,5 +1,7 @@ package de.rieckpil.blog; +import static org.junit.jupiter.api.Assertions.assertEquals; + import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @@ -11,24 +13,23 @@ import org.springframework.test.context.DynamicPropertyRegistry; import org.springframework.test.context.DynamicPropertySource; import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.wait.strategy.HostPortWaitStrategy; -import org.testcontainers.containers.wait.strategy.LogMessageWaitStrategy; import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import org.testcontainers.utility.DockerImageName; -import static org.junit.jupiter.api.Assertions.assertEquals; - @Testcontainers @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) class NotificationControllerSecondIT { @Container - static GenericContainer greenMailContainer = new GenericContainer<>(DockerImageName.parse("greenmail/standalone:1.6.1")) - .waitingFor(Wait.forLogMessage(".*Starting GreenMail standalone.*", 1)) - .withEnv("GREENMAIL_OPTS", "-Dgreenmail.setup.test.smtp -Dgreenmail.hostname=0.0.0.0 -Dgreenmail.users=duke:springboot") - .withExposedPorts(3025); + static GenericContainer greenMailContainer = + new GenericContainer<>(DockerImageName.parse("greenmail/standalone:1.6.1")) + .waitingFor(Wait.forLogMessage(".*Starting GreenMail standalone.*", 1)) + .withEnv( + "GREENMAIL_OPTS", + "-Dgreenmail.setup.test.smtp -Dgreenmail.hostname=0.0.0.0 -Dgreenmail.users=duke:springboot") + .withExposedPorts(3025); @DynamicPropertySource static void configureMailHost(DynamicPropertyRegistry registry) { @@ -36,8 +37,7 @@ static void configureMailHost(DynamicPropertyRegistry registry) { registry.add("spring.mail.port", greenMailContainer::getFirstMappedPort); } - @Autowired - private TestRestTemplate testRestTemplate; + @Autowired private TestRestTemplate testRestTemplate; @Test void shouldSendEmailWithCorrectPayloadToUser() throws Exception { @@ -48,9 +48,9 @@ void shouldSendEmailWithCorrectPayloadToUser() throws Exception { headers.setContentType(MediaType.APPLICATION_JSON); HttpEntity request = new HttpEntity<>(payload, headers); - ResponseEntity response = this.testRestTemplate.postForEntity("/notifications", request, Void.class); + ResponseEntity response = + this.testRestTemplate.postForEntity("/notifications", request, Void.class); assertEquals(200, response.getStatusCodeValue()); - } } diff --git a/spring-boot-test-mockmvc-webtestclient-testresttemplate/pom.xml b/spring-boot-test-mockmvc-webtestclient-testresttemplate/pom.xml index e2969b4c..9ed1b284 100644 --- a/spring-boot-test-mockmvc-webtestclient-testresttemplate/pom.xml +++ b/spring-boot-test-mockmvc-webtestclient-testresttemplate/pom.xml @@ -2,21 +2,18 @@ 4.0.0 + - org.springframework.boot - spring-boot-starter-parent - 2.7.1 - + de.rieckpil.blog + blog-parent + 0.0.1-SNAPSHOT + ../pom.xml de.rieckpil spring-boot-test-mockmvc-webtestclient-testresttemplate 0.0.1-SNAPSHOT - - 17 - - org.springframework.boot diff --git a/spring-boot-test-mockmvc-webtestclient-testresttemplate/src/main/java/de/rieckpil/Application.java b/spring-boot-test-mockmvc-webtestclient-testresttemplate/src/main/java/de/rieckpil/Application.java index de296439..22638758 100644 --- a/spring-boot-test-mockmvc-webtestclient-testresttemplate/src/main/java/de/rieckpil/Application.java +++ b/spring-boot-test-mockmvc-webtestclient-testresttemplate/src/main/java/de/rieckpil/Application.java @@ -9,5 +9,4 @@ public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } - } diff --git a/spring-boot-test-mockmvc-webtestclient-testresttemplate/src/main/java/de/rieckpil/Customer.java b/spring-boot-test-mockmvc-webtestclient-testresttemplate/src/main/java/de/rieckpil/Customer.java index ece5de42..242d4f47 100644 --- a/spring-boot-test-mockmvc-webtestclient-testresttemplate/src/main/java/de/rieckpil/Customer.java +++ b/spring-boot-test-mockmvc-webtestclient-testresttemplate/src/main/java/de/rieckpil/Customer.java @@ -1,8 +1,3 @@ package de.rieckpil; -public record Customer( - String firstName, - String lastName, - Long id -) { -} +public record Customer(String firstName, String lastName, Long id) {} diff --git a/spring-boot-test-mockmvc-webtestclient-testresttemplate/src/main/java/de/rieckpil/CustomerController.java b/spring-boot-test-mockmvc-webtestclient-testresttemplate/src/main/java/de/rieckpil/CustomerController.java index 721ca515..fa184154 100644 --- a/spring-boot-test-mockmvc-webtestclient-testresttemplate/src/main/java/de/rieckpil/CustomerController.java +++ b/spring-boot-test-mockmvc-webtestclient-testresttemplate/src/main/java/de/rieckpil/CustomerController.java @@ -2,7 +2,6 @@ import java.util.ArrayList; import java.util.List; - import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; @@ -15,9 +14,8 @@ @RequestMapping("/api/customers") public class CustomerController { - private static final List CUSTOMER_LIST = new ArrayList<>( - List.of(new Customer("Duke", "Java", 42L)) - ); + private static final List CUSTOMER_LIST = + new ArrayList<>(List.of(new Customer("Duke", "Java", 42L))); @GetMapping public List getAllCustomers() { @@ -26,14 +24,12 @@ public List getAllCustomers() { @PostMapping public ResponseEntity createCustomer( - @RequestBody Customer customer, - UriComponentsBuilder uriComponentsBuilder) { + @RequestBody Customer customer, UriComponentsBuilder uriComponentsBuilder) { CUSTOMER_LIST.add(customer); - return ResponseEntity - .created(uriComponentsBuilder.path("/api/customers/{id}") - .buildAndExpand(customer.id()).toUri()) - .build(); + return ResponseEntity.created( + uriComponentsBuilder.path("/api/customers/{id}").buildAndExpand(customer.id()).toUri()) + .build(); } } diff --git a/spring-boot-test-mockmvc-webtestclient-testresttemplate/src/test/java/de/rieckpil/AdminControllerMockMvcTest.java b/spring-boot-test-mockmvc-webtestclient-testresttemplate/src/test/java/de/rieckpil/AdminControllerMockMvcTest.java index d6d4e50d..4551f7a8 100644 --- a/spring-boot-test-mockmvc-webtestclient-testresttemplate/src/test/java/de/rieckpil/AdminControllerMockMvcTest.java +++ b/spring-boot-test-mockmvc-webtestclient-testresttemplate/src/test/java/de/rieckpil/AdminControllerMockMvcTest.java @@ -1,41 +1,28 @@ package de.rieckpil; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.test.web.servlet.MvcResult; - -import static org.hamcrest.Matchers.is; -import static org.junit.jupiter.api.Assertions.*; - -import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; -import static org.mockito.Mockito.when; -import static org.mockito.Mockito.verify; -import static org.springframework.http.HttpHeaders.ACCEPT; -import static org.springframework.http.MediaType.APPLICATION_JSON; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.model; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.test.web.servlet.MockMvc; + @WebMvcTest(AdminController.class) class AdminControllerMockMvcTest { - @Autowired - private MockMvc mockMvc; + @Autowired private MockMvc mockMvc; @Test void shouldReturnAdminView() throws Exception { this.mockMvc - .perform(get("/admin")) - .andExpect(status().is(200)) - .andExpect(view().name("admin")) - .andExpect(model().attributeExists("secretMessage")); + .perform(get("/admin")) + .andExpect(status().is(200)) + .andExpect(view().name("admin")) + .andExpect(model().attributeExists("secretMessage")); } } diff --git a/spring-boot-test-mockmvc-webtestclient-testresttemplate/src/test/java/de/rieckpil/CustomerControllerMockMvcTest.java b/spring-boot-test-mockmvc-webtestclient-testresttemplate/src/test/java/de/rieckpil/CustomerControllerMockMvcTest.java index ef326e1c..030356bd 100644 --- a/spring-boot-test-mockmvc-webtestclient-testresttemplate/src/test/java/de/rieckpil/CustomerControllerMockMvcTest.java +++ b/spring-boot-test-mockmvc-webtestclient-testresttemplate/src/test/java/de/rieckpil/CustomerControllerMockMvcTest.java @@ -1,20 +1,8 @@ package de.rieckpil; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.test.web.servlet.MvcResult; - import static org.hamcrest.Matchers.greaterThan; -import static org.hamcrest.Matchers.is; -import static org.junit.jupiter.api.Assertions.*; - -import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; -import static org.mockito.Mockito.when; -import static org.mockito.Mockito.verify; import static org.springframework.http.HttpHeaders.ACCEPT; import static org.springframework.http.MediaType.APPLICATION_JSON; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; @@ -24,37 +12,41 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.test.web.servlet.MockMvc; + @WebMvcTest(CustomerController.class) class CustomerControllerMockMvcTest { - @Autowired - private MockMvc mockMvc; + @Autowired private MockMvc mockMvc; @Test void shouldReturnListOfAllCustomers() throws Exception { this.mockMvc - .perform(get("/api/customers") - .header(ACCEPT, APPLICATION_JSON)) - .andExpect(status().is(200)) - .andExpect(content().contentType(APPLICATION_JSON)) - .andExpect(jsonPath("$.size()", greaterThan(0))) - .andDo(print()) - .andReturn(); + .perform(get("/api/customers").header(ACCEPT, APPLICATION_JSON)) + .andExpect(status().is(200)) + .andExpect(content().contentType(APPLICATION_JSON)) + .andExpect(jsonPath("$.size()", greaterThan(0))) + .andDo(print()) + .andReturn(); } @Test void shouldCreateNewCustomers() throws Exception { this.mockMvc - .perform(post("/api/customers") - .contentType(APPLICATION_JSON) - .content(""" + .perform( + post("/api/customers") + .contentType(APPLICATION_JSON) + .content( + """ { "firstName": "Mike", "lastName": "Thomson", "id": 43 } - """) - ) - .andExpect(status().isCreated()); + """)) + .andExpect(status().isCreated()); } } diff --git a/spring-boot-test-mockmvc-webtestclient-testresttemplate/src/test/java/de/rieckpil/CustomerControllerTestRestTemplateTest.java b/spring-boot-test-mockmvc-webtestclient-testresttemplate/src/test/java/de/rieckpil/CustomerControllerTestRestTemplateTest.java index c81c6a82..e0f5972a 100644 --- a/spring-boot-test-mockmvc-webtestclient-testresttemplate/src/test/java/de/rieckpil/CustomerControllerTestRestTemplateTest.java +++ b/spring-boot-test-mockmvc-webtestclient-testresttemplate/src/test/java/de/rieckpil/CustomerControllerTestRestTemplateTest.java @@ -1,7 +1,9 @@ package de.rieckpil; -import java.util.List; +import static org.assertj.core.api.Assertions.assertThat; +import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; +import java.util.List; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @@ -12,27 +14,21 @@ import org.springframework.http.HttpMethod; import org.springframework.http.ResponseEntity; -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; - @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) class CustomerControllerTestRestTemplateTest { - @Autowired - private TestRestTemplate testRestTemplate; + @Autowired private TestRestTemplate testRestTemplate; @Test void shouldReturnListOfAllCustomers() { - ResponseEntity> response = this.testRestTemplate - .exchange("/api/customers", HttpMethod.GET, null, new ParameterizedTypeReference<>() { - }); + ResponseEntity> response = + this.testRestTemplate.exchange( + "/api/customers", HttpMethod.GET, null, new ParameterizedTypeReference<>() {}); - assertThat(response.getStatusCodeValue()) - .isEqualTo(200); + assertThat(response.getStatusCodeValue()).isEqualTo(200); - assertThat(response.getBody()) - .hasSizeGreaterThan(0); + assertThat(response.getBody()).hasSizeGreaterThan(0); } @Test @@ -41,20 +37,21 @@ void shouldCreateNewCustomers() { HttpHeaders requestHeaders = new HttpHeaders(); requestHeaders.add(HttpHeaders.CONTENT_TYPE, APPLICATION_JSON_VALUE); - HttpEntity requestEntity = new HttpEntity<>(""" + HttpEntity requestEntity = + new HttpEntity<>( + """ { "firstName": "Mike", "lastName": "Thomson", "id": 43 } """, - requestHeaders - ); + requestHeaders); - ResponseEntity response = this.testRestTemplate - .exchange("/api/customers", HttpMethod.POST, requestEntity, Void.class); + ResponseEntity response = + this.testRestTemplate.exchange( + "/api/customers", HttpMethod.POST, requestEntity, Void.class); - assertThat(response.getStatusCodeValue()) - .isEqualTo(201); + assertThat(response.getStatusCodeValue()).isEqualTo(201); } } diff --git a/spring-boot-test-mockmvc-webtestclient-testresttemplate/src/test/java/de/rieckpil/CustomerControllerWebTestClientTest.java b/spring-boot-test-mockmvc-webtestclient-testresttemplate/src/test/java/de/rieckpil/CustomerControllerWebTestClientTest.java index f8e1f305..49d22863 100644 --- a/spring-boot-test-mockmvc-webtestclient-testresttemplate/src/test/java/de/rieckpil/CustomerControllerWebTestClientTest.java +++ b/spring-boot-test-mockmvc-webtestclient-testresttemplate/src/test/java/de/rieckpil/CustomerControllerWebTestClientTest.java @@ -1,7 +1,9 @@ package de.rieckpil; -import java.util.List; +import static org.assertj.core.api.Assertions.assertThat; +import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; +import java.util.List; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @@ -9,46 +11,43 @@ import org.springframework.test.web.reactive.server.EntityExchangeResult; import org.springframework.test.web.reactive.server.WebTestClient; -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; - @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) class CustomerControllerWebTestClientTest { - @Autowired - private WebTestClient webTestClient; + @Autowired private WebTestClient webTestClient; @Test void shouldReturnListOfAllCustomers() { - EntityExchangeResult> result = this.webTestClient - .get() - .uri("/api/customers") - .header(HttpHeaders.ACCEPT, APPLICATION_JSON_VALUE) - .exchange() - .expectStatus() - .is2xxSuccessful() - .expectBodyList(Customer.class) - .returnResult(); - - assertThat(result.getResponseBody()) - .hasSizeGreaterThan(1); + EntityExchangeResult> result = + this.webTestClient + .get() + .uri("/api/customers") + .header(HttpHeaders.ACCEPT, APPLICATION_JSON_VALUE) + .exchange() + .expectStatus() + .is2xxSuccessful() + .expectBodyList(Customer.class) + .returnResult(); + + assertThat(result.getResponseBody()).hasSizeGreaterThan(1); } @Test void shouldCreateNewCustomers() { this.webTestClient - .post() - .uri("/api/customers") - .bodyValue(""" + .post() + .uri("/api/customers") + .bodyValue( + """ { "firstName": "Mike", "lastName": "Thomson", "id": 43 } """) - .header(HttpHeaders.CONTENT_TYPE, APPLICATION_JSON_VALUE) - .exchange() - .expectStatus() - .isCreated(); + .header(HttpHeaders.CONTENT_TYPE, APPLICATION_JSON_VALUE) + .exchange() + .expectStatus() + .isCreated(); } } diff --git a/spring-boot-test-slice-annotations/src/main/java/de/rieckpil/blog/Book.java b/spring-boot-test-slice-annotations/src/main/java/de/rieckpil/blog/Book.java index f6a02145..ed0b5756 100644 --- a/spring-boot-test-slice-annotations/src/main/java/de/rieckpil/blog/Book.java +++ b/spring-boot-test-slice-annotations/src/main/java/de/rieckpil/blog/Book.java @@ -1,21 +1,17 @@ package de.rieckpil.blog; -import org.hibernate.annotations.NaturalId; - import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.Id; +import org.hibernate.annotations.NaturalId; @Entity public class Book { - @Id - @GeneratedValue - private Long id; + @Id @GeneratedValue private Long id; - @NaturalId - private String isbn; + @NaturalId private String isbn; @Column(nullable = false) private String title; diff --git a/spring-boot-test-slice-annotations/src/main/java/de/rieckpil/blog/BookRepository.java b/spring-boot-test-slice-annotations/src/main/java/de/rieckpil/blog/BookRepository.java index 7ce6e9b7..e6506dcd 100644 --- a/spring-boot-test-slice-annotations/src/main/java/de/rieckpil/blog/BookRepository.java +++ b/spring-boot-test-slice-annotations/src/main/java/de/rieckpil/blog/BookRepository.java @@ -2,5 +2,4 @@ import org.springframework.data.jpa.repository.JpaRepository; -public interface BookRepository extends JpaRepository { -} +public interface BookRepository extends JpaRepository {} diff --git a/spring-boot-test-slice-annotations/src/main/java/de/rieckpil/blog/Item.java b/spring-boot-test-slice-annotations/src/main/java/de/rieckpil/blog/Item.java index 90a27084..aa4376af 100644 --- a/spring-boot-test-slice-annotations/src/main/java/de/rieckpil/blog/Item.java +++ b/spring-boot-test-slice-annotations/src/main/java/de/rieckpil/blog/Item.java @@ -4,13 +4,11 @@ public class Item { - @Id - private String id; + @Id private String id; private String name; private double price; - private Item() { - } + private Item() {} public Item(String name, double price) { this.name = name; @@ -43,10 +41,6 @@ public void setPrice(double price) { @Override public String toString() { - return "Item{" + - "id='" + id + '\'' + - ", name='" + name + '\'' + - ", price=" + price + - '}'; + return "Item{" + "id='" + id + '\'' + ", name='" + name + '\'' + ", price=" + price + '}'; } } diff --git a/spring-boot-test-slice-annotations/src/main/java/de/rieckpil/blog/PaymentResponse.java b/spring-boot-test-slice-annotations/src/main/java/de/rieckpil/blog/PaymentResponse.java index 2229b5c3..bf66dd22 100644 --- a/spring-boot-test-slice-annotations/src/main/java/de/rieckpil/blog/PaymentResponse.java +++ b/spring-boot-test-slice-annotations/src/main/java/de/rieckpil/blog/PaymentResponse.java @@ -1,28 +1,22 @@ package de.rieckpil.blog; -import com.fasterxml.jackson.annotation.JsonAlias; import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.PropertyNamingStrategy; -import com.fasterxml.jackson.databind.annotation.JsonNaming; - import java.math.BigDecimal; import java.time.LocalDateTime; import java.util.UUID; public class PaymentResponse { - @JsonIgnore - private String id; + @JsonIgnore private String id; private UUID paymentConfirmationCode; @JsonProperty("payment_amount") private BigDecimal amount; - @JsonFormat( - shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd|HH:mm:ss", locale = "en_US") + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd|HH:mm:ss", locale = "en_US") private LocalDateTime paymentTime; public String getId() { diff --git a/spring-boot-test-slice-annotations/src/main/java/de/rieckpil/blog/RandomQuoteClient.java b/spring-boot-test-slice-annotations/src/main/java/de/rieckpil/blog/RandomQuoteClient.java index 572c33fc..8fd1e36a 100644 --- a/spring-boot-test-slice-annotations/src/main/java/de/rieckpil/blog/RandomQuoteClient.java +++ b/spring-boot-test-slice-annotations/src/main/java/de/rieckpil/blog/RandomQuoteClient.java @@ -1,30 +1,32 @@ package de.rieckpil.blog; import com.fasterxml.jackson.databind.JsonNode; +import java.time.Duration; import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.stereotype.Component; import org.springframework.web.client.RestTemplate; -import java.time.Duration; - @Component public class RandomQuoteClient { private final RestTemplate restTemplate; public RandomQuoteClient(RestTemplateBuilder restTemplateBuilder) { - this.restTemplate = restTemplateBuilder - .rootUri("https://quotes.rest") - .setConnectTimeout(Duration.ofSeconds(2)) - .setConnectTimeout(Duration.ofSeconds(2)) - .build(); + this.restTemplate = + restTemplateBuilder + .rootUri("https://quotes.rest") + .setConnectTimeout(Duration.ofSeconds(2)) + .setConnectTimeout(Duration.ofSeconds(2)) + .build(); } public String getRandomQuote() { return this.restTemplate - .getForObject("/qod", JsonNode.class) - .get("contents") - .get("quotes").get(0) - .get("quote").asText(); + .getForObject("/qod", JsonNode.class) + .get("contents") + .get("quotes") + .get(0) + .get("quote") + .asText(); } } diff --git a/spring-boot-test-slice-annotations/src/main/java/de/rieckpil/blog/ShoppingCart.java b/spring-boot-test-slice-annotations/src/main/java/de/rieckpil/blog/ShoppingCart.java index 6911d8bb..ace8ee1d 100644 --- a/spring-boot-test-slice-annotations/src/main/java/de/rieckpil/blog/ShoppingCart.java +++ b/spring-boot-test-slice-annotations/src/main/java/de/rieckpil/blog/ShoppingCart.java @@ -1,19 +1,16 @@ package de.rieckpil.blog; +import java.util.List; import org.springframework.data.annotation.Id; import org.springframework.data.mongodb.core.mapping.Document; -import java.util.List; - @Document public class ShoppingCart { - @Id - private String id; + @Id private String id; private List shoppingCartItems; - public ShoppingCart() { - } + public ShoppingCart() {} public ShoppingCart(String id, List shoppingCartItems) { this.id = id; diff --git a/spring-boot-test-slice-annotations/src/main/java/de/rieckpil/blog/ShoppingCartItem.java b/spring-boot-test-slice-annotations/src/main/java/de/rieckpil/blog/ShoppingCartItem.java index 4c8d8d22..b8d95de4 100644 --- a/spring-boot-test-slice-annotations/src/main/java/de/rieckpil/blog/ShoppingCartItem.java +++ b/spring-boot-test-slice-annotations/src/main/java/de/rieckpil/blog/ShoppingCartItem.java @@ -5,8 +5,7 @@ class ShoppingCartItem { private Item item; private int quantity; - public ShoppingCartItem() { - } + public ShoppingCartItem() {} public ShoppingCartItem(Item item, int quantity) { this.item = item; @@ -35,9 +34,6 @@ public void setQuantity(int quantity) { @Override public String toString() { - return "ShoppingCartItem{" + - "item=" + item + - ", quantity=" + quantity + - '}'; + return "ShoppingCartItem{" + "item=" + item + ", quantity=" + quantity + '}'; } } diff --git a/spring-boot-test-slice-annotations/src/main/java/de/rieckpil/blog/ShoppingCartRepository.java b/spring-boot-test-slice-annotations/src/main/java/de/rieckpil/blog/ShoppingCartRepository.java index daaba316..2bf12ff9 100644 --- a/spring-boot-test-slice-annotations/src/main/java/de/rieckpil/blog/ShoppingCartRepository.java +++ b/spring-boot-test-slice-annotations/src/main/java/de/rieckpil/blog/ShoppingCartRepository.java @@ -2,5 +2,4 @@ import org.springframework.data.repository.CrudRepository; -public interface ShoppingCartRepository extends CrudRepository { -} +public interface ShoppingCartRepository extends CrudRepository {} diff --git a/spring-boot-test-slice-annotations/src/test/java/de/rieckpil/blog/ApplicationTests.java b/spring-boot-test-slice-annotations/src/test/java/de/rieckpil/blog/ApplicationTests.java index 51b85f2a..e8b5bc36 100644 --- a/spring-boot-test-slice-annotations/src/test/java/de/rieckpil/blog/ApplicationTests.java +++ b/spring-boot-test-slice-annotations/src/test/java/de/rieckpil/blog/ApplicationTests.java @@ -1,26 +1,22 @@ package de.rieckpil.blog; +import static org.junit.jupiter.api.Assertions.assertNotNull; + import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; -import static org.junit.jupiter.api.Assertions.assertNotNull; - @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) class ApplicationTests { - @Autowired - private TestRestTemplate testRestTemplate; + @Autowired private TestRestTemplate testRestTemplate; - @Autowired - private RandomQuoteClient randomQuoteClient; + @Autowired private RandomQuoteClient randomQuoteClient; - @Autowired - private ShoppingCartRepository shoppingCartRepository; + @Autowired private ShoppingCartRepository shoppingCartRepository; - @Autowired - private BookRepository bookRepository; + @Autowired private BookRepository bookRepository; @Test void contextLoads() { diff --git a/spring-boot-test-slice-annotations/src/test/java/de/rieckpil/blog/BookRepositoryTest.java b/spring-boot-test-slice-annotations/src/test/java/de/rieckpil/blog/BookRepositoryTest.java index aacfdb6f..b5d296ba 100644 --- a/spring-boot-test-slice-annotations/src/test/java/de/rieckpil/blog/BookRepositoryTest.java +++ b/spring-boot-test-slice-annotations/src/test/java/de/rieckpil/blog/BookRepositoryTest.java @@ -1,26 +1,22 @@ package de.rieckpil.blog; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; import jakarta.persistence.EntityManager; import javax.sql.DataSource; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; @DataJpaTest class BookRepositoryTest { - @Autowired - private DataSource dataSource; + @Autowired private DataSource dataSource; - @Autowired - private EntityManager entityManager; + @Autowired private EntityManager entityManager; - @Autowired - private BookRepository bookRepository; + @Autowired private BookRepository bookRepository; @Test public void testCustomNativeQuery() { diff --git a/spring-boot-test-slice-annotations/src/test/java/de/rieckpil/blog/JdbcAccessTest.java b/spring-boot-test-slice-annotations/src/test/java/de/rieckpil/blog/JdbcAccessTest.java index 4b014d94..11eadf65 100644 --- a/spring-boot-test-slice-annotations/src/test/java/de/rieckpil/blog/JdbcAccessTest.java +++ b/spring-boot-test-slice-annotations/src/test/java/de/rieckpil/blog/JdbcAccessTest.java @@ -1,22 +1,19 @@ package de.rieckpil.blog; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import javax.sql.DataSource; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.jdbc.JdbcTest; import org.springframework.jdbc.core.JdbcTemplate; -import javax.sql.DataSource; - -import static org.junit.jupiter.api.Assertions.assertNotNull; - @JdbcTest public class JdbcAccessTest { - @Autowired - private DataSource dataSource; + @Autowired private DataSource dataSource; - @Autowired - private JdbcTemplate jdbcTemplate; + @Autowired private JdbcTemplate jdbcTemplate; @Test public void shouldReturnBooks() { diff --git a/spring-boot-test-slice-annotations/src/test/java/de/rieckpil/blog/PaymentResponseTest.java b/spring-boot-test-slice-annotations/src/test/java/de/rieckpil/blog/PaymentResponseTest.java index 330935de..d1aa16a3 100644 --- a/spring-boot-test-slice-annotations/src/test/java/de/rieckpil/blog/PaymentResponseTest.java +++ b/spring-boot-test-slice-annotations/src/test/java/de/rieckpil/blog/PaymentResponseTest.java @@ -1,28 +1,25 @@ package de.rieckpil.blog; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertNotNull; + import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.IOException; +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.util.UUID; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.json.JsonTest; import org.springframework.boot.test.json.JacksonTester; import org.springframework.boot.test.json.JsonContent; -import java.io.IOException; -import java.math.BigDecimal; -import java.time.LocalDateTime; -import java.util.UUID; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertNotNull; - @JsonTest class PaymentResponseTest { - @Autowired - private JacksonTester jacksonTester; + @Autowired private JacksonTester jacksonTester; - @Autowired - private ObjectMapper objectMapper; + @Autowired private ObjectMapper objectMapper; @Test public void shouldSerializeObject() throws IOException { @@ -39,7 +36,9 @@ public void shouldSerializeObject() throws IOException { assertThat(result).hasJsonPathStringValue("$.paymentConfirmationCode"); assertThat(result).extractingJsonPathNumberValue("$.payment_amount").isEqualTo(42.50); - assertThat(result).extractingJsonPathStringValue("$.paymentTime").isEqualTo("2020-07-20|19:00:00"); + assertThat(result) + .extractingJsonPathStringValue("$.paymentTime") + .isEqualTo("2020-07-20|19:00:00"); assertThat(result).doesNotHaveJsonPath("$.id"); } } diff --git a/spring-boot-test-slice-annotations/src/test/java/de/rieckpil/blog/RandomQuoteClientTest.java b/spring-boot-test-slice-annotations/src/test/java/de/rieckpil/blog/RandomQuoteClientTest.java index 6d00a7df..f53312c8 100644 --- a/spring-boot-test-slice-annotations/src/test/java/de/rieckpil/blog/RandomQuoteClientTest.java +++ b/spring-boot-test-slice-annotations/src/test/java/de/rieckpil/blog/RandomQuoteClientTest.java @@ -1,6 +1,7 @@ package de.rieckpil.blog; -import org.hamcrest.Matchers; +import static org.junit.jupiter.api.Assertions.assertEquals; + import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.client.RestClientTest; @@ -9,33 +10,30 @@ import org.springframework.test.web.client.match.MockRestRequestMatchers; import org.springframework.test.web.client.response.MockRestResponseCreators; -import static org.junit.jupiter.api.Assertions.assertEquals; - @RestClientTest(RandomQuoteClient.class) class RandomQuoteClientTest { - @Autowired - private RandomQuoteClient randomQuoteClient; + @Autowired private RandomQuoteClient randomQuoteClient; - @Autowired - private MockRestServiceServer mockRestServiceServer; + @Autowired private MockRestServiceServer mockRestServiceServer; @Test public void shouldReturnQuoteFromRemoteSystem() { - String response = "{" + - "\"contents\": {"+ - "\"quotes\": ["+ - "{"+ - "\"author\": \"duke\"," + - "\"quote\": \"Lorem ipsum\""+ - "}"+ - "]"+ - "}" + - "}"; + String response = + "{" + + "\"contents\": {" + + "\"quotes\": [" + + "{" + + "\"author\": \"duke\"," + + "\"quote\": \"Lorem ipsum\"" + + "}" + + "]" + + "}" + + "}"; this.mockRestServiceServer - .expect(MockRestRequestMatchers.requestTo("/qod")) - .andRespond(MockRestResponseCreators.withSuccess(response, MediaType.APPLICATION_JSON)); + .expect(MockRestRequestMatchers.requestTo("/qod")) + .andRespond(MockRestResponseCreators.withSuccess(response, MediaType.APPLICATION_JSON)); String result = randomQuoteClient.getRandomQuote(); diff --git a/spring-boot-test-slice-annotations/src/test/java/de/rieckpil/blog/ShoppingCartControllerTest.java b/spring-boot-test-slice-annotations/src/test/java/de/rieckpil/blog/ShoppingCartControllerTest.java index 33152088..9815ada6 100644 --- a/spring-boot-test-slice-annotations/src/test/java/de/rieckpil/blog/ShoppingCartControllerTest.java +++ b/spring-boot-test-slice-annotations/src/test/java/de/rieckpil/blog/ShoppingCartControllerTest.java @@ -1,5 +1,11 @@ package de.rieckpil.blog; +import static org.mockito.Mockito.when; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import java.util.List; import org.hamcrest.Matchers; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -7,35 +13,27 @@ import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.test.web.servlet.MockMvc; -import java.util.List; - -import static org.mockito.Mockito.when; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - @WebMvcTest(ShoppingCartController.class) class ShoppingCartControllerTest { - @Autowired - private MockMvc mockMvc; + @Autowired private MockMvc mockMvc; - @MockBean - private ShoppingCartRepository shoppingCartRepository; + @MockBean private ShoppingCartRepository shoppingCartRepository; @Test public void shouldReturnAllShoppingCarts() throws Exception { - when(shoppingCartRepository.findAll()).thenReturn( - List.of(new ShoppingCart("42", - List.of(new ShoppingCartItem( - new Item("MacBook", 999.9), 2) - )))); - - this.mockMvc.perform(get("/api/carts")) - .andExpect(status().isOk()) - .andExpect(jsonPath("$[0].id", Matchers.is("42"))) - .andExpect(jsonPath("$[0].cartItems.length()", Matchers.is(1))) - .andExpect(jsonPath("$[0].cartItems[0].item.name", Matchers.is("MacBook"))) - .andExpect(jsonPath("$[0].cartItems[0].quantity", Matchers.is(2))); + when(shoppingCartRepository.findAll()) + .thenReturn( + List.of( + new ShoppingCart( + "42", List.of(new ShoppingCartItem(new Item("MacBook", 999.9), 2))))); + + this.mockMvc + .perform(get("/api/carts")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$[0].id", Matchers.is("42"))) + .andExpect(jsonPath("$[0].cartItems.length()", Matchers.is(1))) + .andExpect(jsonPath("$[0].cartItems[0].item.name", Matchers.is("MacBook"))) + .andExpect(jsonPath("$[0].cartItems[0].quantity", Matchers.is(2))); } } diff --git a/spring-boot-test-slice-annotations/src/test/java/de/rieckpil/blog/ShoppingCartRepositoryTest.java b/spring-boot-test-slice-annotations/src/test/java/de/rieckpil/blog/ShoppingCartRepositoryTest.java index b38e0723..e5eaa8dc 100644 --- a/spring-boot-test-slice-annotations/src/test/java/de/rieckpil/blog/ShoppingCartRepositoryTest.java +++ b/spring-boot-test-slice-annotations/src/test/java/de/rieckpil/blog/ShoppingCartRepositoryTest.java @@ -1,29 +1,24 @@ package de.rieckpil.blog; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import java.util.List; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.data.mongo.DataMongoTest; import org.springframework.data.mongodb.core.MongoTemplate; -import java.util.List; - -import static org.junit.jupiter.api.Assertions.assertNotNull; - @DataMongoTest class ShoppingCartRepositoryTest { - @Autowired - private MongoTemplate mongoTemplate; + @Autowired private MongoTemplate mongoTemplate; - @Autowired - private ShoppingCartRepository shoppingCartRepository; + @Autowired private ShoppingCartRepository shoppingCartRepository; @Test public void shouldCreateContext() { - shoppingCartRepository.save(new ShoppingCart("42", - List.of(new ShoppingCartItem( - new Item("MacBook", 999.9), 2) - ))); + shoppingCartRepository.save( + new ShoppingCart("42", List.of(new ShoppingCartItem(new Item("MacBook", 999.9), 2)))); assertNotNull(mongoTemplate); assertNotNull(shoppingCartRepository); diff --git a/spring-boot-test-spring-events/pom.xml b/spring-boot-test-spring-events/pom.xml index c332bcb0..bcc5a091 100644 --- a/spring-boot-test-spring-events/pom.xml +++ b/spring-boot-test-spring-events/pom.xml @@ -4,21 +4,16 @@ 4.0.0 - org.springframework.boot - spring-boot-starter-parent - 2.4.2 - + de.rieckpil.blog + blog-parent + 0.0.1-SNAPSHOT + ../pom.xml - de.rieckpil.blog spring-boot-test-spring-events 0.0.1-SNAPSHOT spring-boot-test-spring-events - - 11 - - org.springframework.boot diff --git a/spring-boot-test-spring-events/src/main/java/de/rieckpil/blog/Application.java b/spring-boot-test-spring-events/src/main/java/de/rieckpil/blog/Application.java index bd5e4c56..6511f3c1 100644 --- a/spring-boot-test-spring-events/src/main/java/de/rieckpil/blog/Application.java +++ b/spring-boot-test-spring-events/src/main/java/de/rieckpil/blog/Application.java @@ -9,5 +9,4 @@ public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } - } diff --git a/spring-boot-test-spring-events/src/main/java/de/rieckpil/blog/UserController.java b/spring-boot-test-spring-events/src/main/java/de/rieckpil/blog/UserController.java index dac076a3..659708dc 100644 --- a/spring-boot-test-spring-events/src/main/java/de/rieckpil/blog/UserController.java +++ b/spring-boot-test-spring-events/src/main/java/de/rieckpil/blog/UserController.java @@ -19,14 +19,12 @@ public UserController(UserService userService) { @PostMapping public ResponseEntity createNewUser( - @RequestBody String username, - UriComponentsBuilder uriComponentsBuilder) { + @RequestBody String username, UriComponentsBuilder uriComponentsBuilder) { Long id = this.userService.createUser(username); - return ResponseEntity - .created(uriComponentsBuilder.path("/api/users/{id}").buildAndExpand(id).toUri()) - .build(); + return ResponseEntity.created( + uriComponentsBuilder.path("/api/users/{id}").buildAndExpand(id).toUri()) + .build(); } - } diff --git a/spring-boot-test-spring-events/src/main/java/de/rieckpil/blog/UserCreationEvent.java b/spring-boot-test-spring-events/src/main/java/de/rieckpil/blog/UserCreationEvent.java index 6ee209eb..c1ca29ed 100644 --- a/spring-boot-test-spring-events/src/main/java/de/rieckpil/blog/UserCreationEvent.java +++ b/spring-boot-test-spring-events/src/main/java/de/rieckpil/blog/UserCreationEvent.java @@ -21,13 +21,16 @@ public Long getId() { return id; } - @Override public String toString() { - return "UserCreationEvent{" + - "username='" + username + '\'' + - ", id=" + id + - ", timestamp=" + super.getTimestamp() + - '}'; + return "UserCreationEvent{" + + "username='" + + username + + '\'' + + ", id=" + + id + + ", timestamp=" + + super.getTimestamp() + + '}'; } } diff --git a/spring-boot-test-spring-events/src/main/java/de/rieckpil/blog/UserService.java b/spring-boot-test-spring-events/src/main/java/de/rieckpil/blog/UserService.java index bb85c877..6616ecf4 100644 --- a/spring-boot-test-spring-events/src/main/java/de/rieckpil/blog/UserService.java +++ b/spring-boot-test-spring-events/src/main/java/de/rieckpil/blog/UserService.java @@ -1,11 +1,10 @@ package de.rieckpil.blog; -import org.springframework.context.ApplicationEventPublisher; -import org.springframework.stereotype.Service; - import java.util.ArrayList; import java.util.List; import java.util.concurrent.ThreadLocalRandom; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.stereotype.Service; @Service public class UserService { diff --git a/spring-boot-test-spring-events/src/test/java/de/rieckpil/blog/ApplicationIT.java b/spring-boot-test-spring-events/src/test/java/de/rieckpil/blog/ApplicationIT.java index 84eacaa8..3b77ec02 100644 --- a/spring-boot-test-spring-events/src/test/java/de/rieckpil/blog/ApplicationIT.java +++ b/spring-boot-test-spring-events/src/test/java/de/rieckpil/blog/ApplicationIT.java @@ -1,30 +1,29 @@ package de.rieckpil.blog; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment; + import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.http.ResponseEntity; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment; - @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) class ApplicationIT { - @Autowired - private TestRestTemplate testRestTemplate; + @Autowired private TestRestTemplate testRestTemplate; @Test void shouldCreateUserAndPerformReporting() { - ResponseEntity result = this.testRestTemplate - .postForEntity("/api/users", "duke", Void.class); + ResponseEntity result = + this.testRestTemplate.postForEntity("/api/users", "duke", Void.class); assertEquals(201, result.getStatusCodeValue()); - assertTrue(result.getHeaders().containsKey("Location"), - "Response doesn't contain Location header"); + assertTrue( + result.getHeaders().containsKey("Location"), "Response doesn't contain Location header"); // additional assertion to verify the counter was incremented // additional assertion that a new message is part of the queue diff --git a/spring-boot-test-spring-events/src/test/java/de/rieckpil/blog/UserServiceFullContextTest.java b/spring-boot-test-spring-events/src/test/java/de/rieckpil/blog/UserServiceFullContextTest.java index 3c568b5b..94fc6e4f 100644 --- a/spring-boot-test-spring-events/src/test/java/de/rieckpil/blog/UserServiceFullContextTest.java +++ b/spring-boot-test-spring-events/src/test/java/de/rieckpil/blog/UserServiceFullContextTest.java @@ -1,29 +1,21 @@ package de.rieckpil.blog; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.List; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.TestInstance; -import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.context.ApplicationEventPublisher; -import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.event.ApplicationEvents; import org.springframework.test.context.event.RecordApplicationEvents; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -import java.util.List; - -import static org.junit.jupiter.api.Assertions.assertEquals; @SpringBootTest @RecordApplicationEvents class UserServiceFullContextTest { - @Autowired - private ApplicationEvents applicationEvents; + @Autowired private ApplicationEvents applicationEvents; - @Autowired - private UserService userService; + @Autowired private UserService userService; @Test void userCreationShouldPublishEvent() { @@ -32,10 +24,11 @@ void userCreationShouldPublishEvent() { this.userService.createUser("duke"); - assertEquals(1, applicationEvents - .stream(UserCreationEvent.class) - .filter(event -> event.getUsername().equals("duke")) - .count()); + assertEquals( + 1, + applicationEvents.stream(UserCreationEvent.class) + .filter(event -> event.getUsername().equals("duke")) + .count()); // There are multiple events recorded // PrepareInstanceEvent @@ -56,4 +49,3 @@ void batchUserCreationShouldPublishEvents(@Autowired ApplicationEvents events) { assertEquals(3, events.stream(UserCreationEvent.class).count()); } } - diff --git a/spring-boot-test-spring-events/src/test/java/de/rieckpil/blog/UserServicePerClassTest.java b/spring-boot-test-spring-events/src/test/java/de/rieckpil/blog/UserServicePerClassTest.java index ea1e2ab0..89084ef1 100644 --- a/spring-boot-test-spring-events/src/test/java/de/rieckpil/blog/UserServicePerClassTest.java +++ b/spring-boot-test-spring-events/src/test/java/de/rieckpil/blog/UserServicePerClassTest.java @@ -1,5 +1,8 @@ package de.rieckpil.blog; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.List; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; @@ -8,30 +11,25 @@ import org.springframework.test.context.event.RecordApplicationEvents; import org.springframework.test.context.junit.jupiter.SpringExtension; -import java.util.List; - -import static org.junit.jupiter.api.Assertions.assertEquals; - @RecordApplicationEvents @ExtendWith(SpringExtension.class) @ContextConfiguration(classes = UserService.class) class UserServicePerClassTest { - @Autowired - private ApplicationEvents applicationEvents; + @Autowired private ApplicationEvents applicationEvents; - @Autowired - private UserService userService; + @Autowired private UserService userService; @Test void userCreationShouldPublishEvent() { this.userService.createUser("duke"); - assertEquals(1, applicationEvents - .stream(UserCreationEvent.class) - .filter(event -> event.getUsername().equals("duke")) - .count()); + assertEquals( + 1, + applicationEvents.stream(UserCreationEvent.class) + .filter(event -> event.getUsername().equals("duke")) + .count()); applicationEvents.stream().forEach(System.out::println); } diff --git a/spring-boot-test-spring-events/src/test/java/de/rieckpil/blog/UserServiceTest.java b/spring-boot-test-spring-events/src/test/java/de/rieckpil/blog/UserServiceTest.java index adb4ff1e..c79b7c66 100644 --- a/spring-boot-test-spring-events/src/test/java/de/rieckpil/blog/UserServiceTest.java +++ b/spring-boot-test-spring-events/src/test/java/de/rieckpil/blog/UserServiceTest.java @@ -1,5 +1,8 @@ package de.rieckpil.blog; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.List; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; @@ -8,30 +11,25 @@ import org.springframework.test.context.event.RecordApplicationEvents; import org.springframework.test.context.junit.jupiter.SpringExtension; -import java.util.List; - -import static org.junit.jupiter.api.Assertions.assertEquals; - @RecordApplicationEvents @ExtendWith(SpringExtension.class) @ContextConfiguration(classes = UserService.class) class UserServiceTest { - @Autowired - private ApplicationEvents applicationEvents; + @Autowired private ApplicationEvents applicationEvents; - @Autowired - private UserService userService; + @Autowired private UserService userService; @Test void userCreationShouldPublishEvent() { this.userService.createUser("duke"); - assertEquals(1, applicationEvents - .stream(UserCreationEvent.class) - .filter(event -> event.getUsername().equals("duke")) - .count()); + assertEquals( + 1, + applicationEvents.stream(UserCreationEvent.class) + .filter(event -> event.getUsername().equals("duke")) + .count()); applicationEvents.stream().forEach(System.out::println); } diff --git a/spring-boot-test-spring-events/src/test/java/de/rieckpil/blog/UserServiceUnitTest.java b/spring-boot-test-spring-events/src/test/java/de/rieckpil/blog/UserServiceUnitTest.java index 26447275..ff0188a8 100644 --- a/spring-boot-test-spring-events/src/test/java/de/rieckpil/blog/UserServiceUnitTest.java +++ b/spring-boot-test-spring-events/src/test/java/de/rieckpil/blog/UserServiceUnitTest.java @@ -1,32 +1,23 @@ package de.rieckpil.blog; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.ArgumentMatchers.any; + +import java.util.List; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.*; import org.mockito.junit.jupiter.MockitoExtension; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationEventPublisher; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.event.ApplicationEvents; -import org.springframework.test.context.event.RecordApplicationEvents; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -import java.util.List; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.mockito.ArgumentMatchers.any; @ExtendWith(MockitoExtension.class) class UserServiceUnitTest { - @Mock - private ApplicationEventPublisher applicationEventPublisher; + @Mock private ApplicationEventPublisher applicationEventPublisher; - @Captor - private ArgumentCaptor eventArgumentCaptor; + @Captor private ArgumentCaptor eventArgumentCaptor; - @InjectMocks - private UserService userService; + @InjectMocks private UserService userService; @Test void userCreationShouldPublishEvent() { @@ -42,8 +33,7 @@ void userCreationShouldPublishEvent() { void batchUserCreationShouldPublishEvents() { List result = this.userService.createUser(List.of("duke", "mike", "alice")); - Mockito - .verify(applicationEventPublisher, Mockito.times(3)) - .publishEvent(any(UserCreationEvent.class)); + Mockito.verify(applicationEventPublisher, Mockito.times(3)) + .publishEvent(any(UserCreationEvent.class)); } } diff --git a/spring-boot-testing-tips-and-tricks/pom.xml b/spring-boot-testing-tips-and-tricks/pom.xml index 57118da4..e4553877 100644 --- a/spring-boot-testing-tips-and-tricks/pom.xml +++ b/spring-boot-testing-tips-and-tricks/pom.xml @@ -1,24 +1,18 @@ - + 4.0.0 + - org.springframework.boot - spring-boot-starter-parent - 2.5.5 - + de.rieckpil.blog + blog-parent + 0.0.1-SNAPSHOT + ../pom.xml - de.rieckpil.blog spring-boot-testing-tips-and-tricks 0.0.1-SNAPSHOT spring-boot-testing-tips-and-tricks - - 11 - 1.16.0 - - org.springframework.boot @@ -66,19 +60,6 @@ org.asciidoctor asciidoctor-maven-plugin 1.5.8 - - - generate-docs - prepare-package - - process-asciidoc - - - html - book - - - org.springframework.restdocs @@ -86,21 +67,17 @@ ${spring-restdocs.version} - - - org.springframework.boot - spring-boot-maven-plugin - - - org.apache.maven.plugins - maven-failsafe-plugin - 3.0.0-M5 + generate-docs - integration-test - verify + process-asciidoc + prepare-package + + html + book + diff --git a/spring-boot-testing-tips-and-tricks/src/main/java/de/rieckpil/blog/Application.java b/spring-boot-testing-tips-and-tricks/src/main/java/de/rieckpil/blog/Application.java index bd5e4c56..6511f3c1 100644 --- a/spring-boot-testing-tips-and-tricks/src/main/java/de/rieckpil/blog/Application.java +++ b/spring-boot-testing-tips-and-tricks/src/main/java/de/rieckpil/blog/Application.java @@ -9,5 +9,4 @@ public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } - } diff --git a/spring-boot-testing-tips-and-tricks/src/main/java/de/rieckpil/blog/Customer.java b/spring-boot-testing-tips-and-tricks/src/main/java/de/rieckpil/blog/Customer.java index 8e1b7dca..443fc5e4 100644 --- a/spring-boot-testing-tips-and-tricks/src/main/java/de/rieckpil/blog/Customer.java +++ b/spring-boot-testing-tips-and-tricks/src/main/java/de/rieckpil/blog/Customer.java @@ -5,8 +5,7 @@ public class Customer { private String firstName; private String lastName; - public Customer() { - } + public Customer() {} public Customer(String firstName, String lastName) { this.firstName = firstName; diff --git a/spring-boot-testing-tips-and-tricks/src/main/java/de/rieckpil/blog/CustomerController.java b/spring-boot-testing-tips-and-tricks/src/main/java/de/rieckpil/blog/CustomerController.java index 55653080..1ab51696 100644 --- a/spring-boot-testing-tips-and-tricks/src/main/java/de/rieckpil/blog/CustomerController.java +++ b/spring-boot-testing-tips-and-tricks/src/main/java/de/rieckpil/blog/CustomerController.java @@ -1,11 +1,10 @@ package de.rieckpil.blog; +import java.util.List; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import org.springframework.web.util.UriComponentsBuilder; -import java.util.List; - @RestController @RequestMapping("/api/customers") public class CustomerController { @@ -16,12 +15,10 @@ public List getAllCustomers() { } @PostMapping - public ResponseEntity createNewCustomer(@RequestBody Customer request, UriComponentsBuilder uriComponentsBuilder) { - return ResponseEntity - .created(uriComponentsBuilder - .path("/api/customers/{id}") - .buildAndExpand("42") - .toUri()) - .build(); + public ResponseEntity createNewCustomer( + @RequestBody Customer request, UriComponentsBuilder uriComponentsBuilder) { + return ResponseEntity.created( + uriComponentsBuilder.path("/api/customers/{id}").buildAndExpand("42").toUri()) + .build(); } } diff --git a/spring-boot-testing-tips-and-tricks/src/test/java/de/rieckpil/blog/ApplicationConfigurationIT.java b/spring-boot-testing-tips-and-tricks/src/test/java/de/rieckpil/blog/ApplicationConfigurationIT.java index 5a9ae545..d2c545ef 100644 --- a/spring-boot-testing-tips-and-tricks/src/test/java/de/rieckpil/blog/ApplicationConfigurationIT.java +++ b/spring-boot-testing-tips-and-tricks/src/test/java/de/rieckpil/blog/ApplicationConfigurationIT.java @@ -1,5 +1,7 @@ package de.rieckpil.blog; +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment; + import org.junit.jupiter.api.Test; import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; @@ -8,22 +10,18 @@ import org.springframework.core.env.Environment; import org.springframework.test.context.ActiveProfiles; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment; - @SpringBootTest( - webEnvironment = WebEnvironment.RANDOM_PORT, - properties = { - "my.custom.property=inlined", - "spring.main.banner-mode=off" // don't do this when Josh Long is pairing with you - }) + webEnvironment = WebEnvironment.RANDOM_PORT, + properties = { + "my.custom.property=inlined", + "spring.main.banner-mode=off" // don't do this when Josh Long is pairing with you + }) @ActiveProfiles("integration-test") class ApplicationConfigurationIT { - @Autowired - private Environment environment; + @Autowired private Environment environment; - @MockBean - private CustomerService customerService; + @MockBean private CustomerService customerService; @Test void shouldPrintConfigurationValues() { diff --git a/spring-boot-testing-tips-and-tricks/src/test/java/de/rieckpil/blog/ApplicationDefinedPortIT.java b/spring-boot-testing-tips-and-tricks/src/test/java/de/rieckpil/blog/ApplicationDefinedPortIT.java index 43d881a9..d17fa1ed 100644 --- a/spring-boot-testing-tips-and-tricks/src/test/java/de/rieckpil/blog/ApplicationDefinedPortIT.java +++ b/spring-boot-testing-tips-and-tricks/src/test/java/de/rieckpil/blog/ApplicationDefinedPortIT.java @@ -1,25 +1,20 @@ package de.rieckpil.blog; +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment; + import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.web.server.LocalManagementPort; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.web.server.LocalServerPort; - -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.test.web.server.LocalManagementPort; +import org.springframework.boot.test.web.server.LocalServerPort; @SpringBootTest( - webEnvironment = WebEnvironment.DEFINED_PORT, - properties = { - "server.port=8042", - "management.server.port=9042" - }) + webEnvironment = WebEnvironment.DEFINED_PORT, + properties = {"server.port=8042", "management.server.port=9042"}) class ApplicationDefinedPortIT { - @LocalServerPort - private Integer port; + @LocalServerPort private Integer port; - @LocalManagementPort - private Integer managementPort; + @LocalManagementPort private Integer managementPort; @Test void printPortsInUse() { diff --git a/spring-boot-testing-tips-and-tricks/src/test/java/de/rieckpil/blog/ApplicationIT.java b/spring-boot-testing-tips-and-tricks/src/test/java/de/rieckpil/blog/ApplicationIT.java index abd51cb3..b2f838f5 100644 --- a/spring-boot-testing-tips-and-tricks/src/test/java/de/rieckpil/blog/ApplicationIT.java +++ b/spring-boot-testing-tips-and-tricks/src/test/java/de/rieckpil/blog/ApplicationIT.java @@ -1,30 +1,26 @@ package de.rieckpil.blog; +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment; + import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.actuate.autoconfigure.web.server.LocalManagementPort; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.boot.test.web.server.LocalManagementPort; +import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.test.web.reactive.server.WebTestClient; import org.springframework.web.reactive.function.client.WebClient; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment; - @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) class ApplicationIT { - @Autowired - private WebTestClient webTestClient; // available with Spring WebFlux + @Autowired private WebTestClient webTestClient; // available with Spring WebFlux - @Autowired - private TestRestTemplate testRestTemplate; // available with Spring Web MVC + @Autowired private TestRestTemplate testRestTemplate; // available with Spring Web MVC - @LocalServerPort - private Integer port; + @LocalServerPort private Integer port; - @LocalManagementPort - private Integer managementPort; + @LocalManagementPort private Integer managementPort; @Test void printPortsInUse() { @@ -36,15 +32,8 @@ void printPortsInUse() { void httpClientExample() { // no need for this - WebClient webClient = WebClient.builder() - .baseUrl("http://localhost:" + port) - .build(); - - this.webTestClient - .get() - .uri("/api/customers") - .exchange() - .expectStatus().is2xxSuccessful(); + WebClient webClient = WebClient.builder().baseUrl("http://localhost:" + port).build(); + this.webTestClient.get().uri("/api/customers").exchange().expectStatus().is2xxSuccessful(); } } diff --git a/spring-boot-testing-tips-and-tricks/src/test/java/de/rieckpil/blog/ApplicationTest.java b/spring-boot-testing-tips-and-tricks/src/test/java/de/rieckpil/blog/ApplicationTest.java index b1dc13b4..63356999 100644 --- a/spring-boot-testing-tips-and-tricks/src/test/java/de/rieckpil/blog/ApplicationTest.java +++ b/spring-boot-testing-tips-and-tricks/src/test/java/de/rieckpil/blog/ApplicationTest.java @@ -1,22 +1,20 @@ package de.rieckpil.blog; // JUnit Jupiter (part of JUnit 5) +import static org.springframework.boot.test.context.SpringBootTest.*; + import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.server.LocalServerPort; - -import static org.springframework.boot.test.context.SpringBootTest.*; +import org.springframework.boot.test.web.server.LocalServerPort; @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) class ApplicationTest { - @LocalServerPort - private Integer port; + @LocalServerPort private Integer port; - @Autowired - private TestRestTemplate testRestTemplate; + @Autowired private TestRestTemplate testRestTemplate; @Test void accessApplication() { diff --git a/spring-boot-testing-tips-and-tricks/src/test/java/de/rieckpil/blog/CustomerControllerTest.java b/spring-boot-testing-tips-and-tricks/src/test/java/de/rieckpil/blog/CustomerControllerTest.java index 6389b663..83f78907 100644 --- a/spring-boot-testing-tips-and-tricks/src/test/java/de/rieckpil/blog/CustomerControllerTest.java +++ b/spring-boot-testing-tips-and-tricks/src/test/java/de/rieckpil/blog/CustomerControllerTest.java @@ -1,5 +1,10 @@ package de.rieckpil.blog; +import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + import org.hamcrest.Matchers; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -12,17 +17,11 @@ import org.springframework.restdocs.mockmvc.RestDocumentationResultHandler; import org.springframework.test.web.servlet.MockMvc; -import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; - @AutoConfigureRestDocs @WebMvcTest(CustomerController.class) class CustomerControllerTest { - @Autowired - private MockMvc mockMvc; + @Autowired private MockMvc mockMvc; @TestConfiguration static class ResultHandlerConfiguration { @@ -36,23 +35,22 @@ public RestDocumentationResultHandler restDocumentation() { @Test void allCustomers() throws Exception { this.mockMvc - .perform(get("/api/customers") - .param("amount", "42")) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.size()", Matchers.equalTo(1))) - .andExpect(jsonPath("$[0].firstName", Matchers.equalTo("Duke"))) - .andExpect(jsonPath("$[0].lastName", Matchers.equalTo("Java"))) - .andDo(document("{method-name}")); + .perform(get("/api/customers").param("amount", "42")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.size()", Matchers.equalTo(1))) + .andExpect(jsonPath("$[0].firstName", Matchers.equalTo("Duke"))) + .andExpect(jsonPath("$[0].lastName", Matchers.equalTo("Java"))) + .andDo(document("{method-name}")); } @Test void createCustomer() throws Exception { this.mockMvc - .perform(post("/api/customers") - .content("{\"firstName\":\"Alice\", \"lastName\":\"Anderson\"}") - .contentType(MediaType.APPLICATION_JSON)) - .andExpect(status().isCreated()) - .andExpect(header().exists("Location")); + .perform( + post("/api/customers") + .content("{\"firstName\":\"Alice\", \"lastName\":\"Anderson\"}") + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isCreated()) + .andExpect(header().exists("Location")); } } - diff --git a/spring-boot-testing-tips-and-tricks/src/test/java/de/rieckpil/blog/CustomerServiceTest.java b/spring-boot-testing-tips-and-tricks/src/test/java/de/rieckpil/blog/CustomerServiceTest.java index ce0137da..b09a60e6 100644 --- a/spring-boot-testing-tips-and-tricks/src/test/java/de/rieckpil/blog/CustomerServiceTest.java +++ b/spring-boot-testing-tips-and-tricks/src/test/java/de/rieckpil/blog/CustomerServiceTest.java @@ -1,22 +1,20 @@ package de.rieckpil.blog; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.when; + import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.Mockito.when; - // Don't do the following - the same can be tested with a much faster unit test @SpringBootTest class CustomerServiceTest { - @Autowired - private CustomerService cut; + @Autowired private CustomerService cut; - @MockBean - private CustomerRepository customerRepository; + @MockBean private CustomerRepository customerRepository; @Test void shouldRegisterNewCustomer() { diff --git a/spring-boot-testing-tips-and-tricks/src/test/java/de/rieckpil/blog/DefinedPortApplicationTest.java b/spring-boot-testing-tips-and-tricks/src/test/java/de/rieckpil/blog/DefinedPortApplicationTest.java index d21f64fe..4ff631ba 100644 --- a/spring-boot-testing-tips-and-tricks/src/test/java/de/rieckpil/blog/DefinedPortApplicationTest.java +++ b/spring-boot-testing-tips-and-tricks/src/test/java/de/rieckpil/blog/DefinedPortApplicationTest.java @@ -1,20 +1,17 @@ package de.rieckpil.blog; +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment; + import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.server.LocalServerPort; - -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.test.web.server.LocalServerPort; @Disabled("Will fail because other IT already launches on the defined port") @SpringBootTest(webEnvironment = WebEnvironment.DEFINED_PORT) class DefinedPortApplicationTest { - @LocalServerPort - private Integer port; + @LocalServerPort private Integer port; @Test void accessApplication() { diff --git a/spring-boot-testing-tips-and-tricks/src/test/java/de/rieckpil/blog/FirstTest.java b/spring-boot-testing-tips-and-tricks/src/test/java/de/rieckpil/blog/FirstTest.java index f2e8841c..95e24392 100644 --- a/spring-boot-testing-tips-and-tricks/src/test/java/de/rieckpil/blog/FirstTest.java +++ b/spring-boot-testing-tips-and-tricks/src/test/java/de/rieckpil/blog/FirstTest.java @@ -1,14 +1,14 @@ package de.rieckpil.blog; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertThrows; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + public class FirstTest { @BeforeEach diff --git a/spring-boot-testing-tips-and-tricks/src/test/java/de/rieckpil/blog/JsonTest.java b/spring-boot-testing-tips-and-tricks/src/test/java/de/rieckpil/blog/JsonTest.java index 5739e01b..a3b7931c 100644 --- a/spring-boot-testing-tips-and-tricks/src/test/java/de/rieckpil/blog/JsonTest.java +++ b/spring-boot-testing-tips-and-tricks/src/test/java/de/rieckpil/blog/JsonTest.java @@ -1,12 +1,12 @@ package de.rieckpil.blog; +import static org.junit.jupiter.api.Assertions.assertEquals; + import com.jayway.jsonpath.JsonPath; import org.json.JSONException; import org.junit.jupiter.api.Test; import org.skyscreamer.jsonassert.JSONAssert; -import static org.junit.jupiter.api.Assertions.assertEquals; - class JsonTest { @Test diff --git a/spring-boot-testing-tips-and-tricks/src/test/java/de/rieckpil/blog/PricingServiceTest.java b/spring-boot-testing-tips-and-tricks/src/test/java/de/rieckpil/blog/PricingServiceTest.java index a65294f6..52290f1e 100644 --- a/spring-boot-testing-tips-and-tricks/src/test/java/de/rieckpil/blog/PricingServiceTest.java +++ b/spring-boot-testing-tips-and-tricks/src/test/java/de/rieckpil/blog/PricingServiceTest.java @@ -1,18 +1,17 @@ package de.rieckpil.blog; -import java.math.BigDecimal; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import java.math.BigDecimal; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + // register the Mockito JUnit Jupiter extension @ExtendWith(MockitoExtension.class) public class PricingServiceTest { @@ -20,19 +19,19 @@ public class PricingServiceTest { @Mock // Instruct Mockito to mock this object private ProductVerifier mockedProductVerifier; - @Mock - private ProductReporter mockedProductReporter; + @Mock private ProductReporter mockedProductReporter; @Test void shouldReturnCheapPriceWhenProductIsInStockOfCompetitor() { - //Specify what boolean value to return for this test + // Specify what boolean value to return for this test when(mockedProductVerifier.isCurrentlyInStockOfCompetitor("AirPods")).thenReturn(true); - PricingService classUnderTest = new PricingService(mockedProductVerifier, mockedProductReporter); + PricingService classUnderTest = + new PricingService(mockedProductVerifier, mockedProductReporter); assertEquals(new BigDecimal("99.99"), classUnderTest.calculatePrice("AirPods")); - //verify the interaction + // verify the interaction verify(mockedProductReporter).notify("AirPods"); } @@ -40,7 +39,8 @@ void shouldReturnCheapPriceWhenProductIsInStockOfCompetitor() { void hamcrestExample() { when(mockedProductVerifier.isCurrentlyInStockOfCompetitor("AirPods")).thenReturn(true); - PricingService classUnderTest = new PricingService(mockedProductVerifier, mockedProductReporter); + PricingService classUnderTest = + new PricingService(mockedProductVerifier, mockedProductReporter); assertThat(classUnderTest.calculatePrice("AirPods"), equalTo(new BigDecimal("99.99"))); @@ -51,11 +51,12 @@ void hamcrestExample() { void assertjExample() { when(mockedProductVerifier.isCurrentlyInStockOfCompetitor("AirPods")).thenReturn(true); - PricingService classUnderTest = new PricingService(mockedProductVerifier, mockedProductReporter); + PricingService classUnderTest = + new PricingService(mockedProductVerifier, mockedProductReporter); - org.assertj.core.api.Assertions.assertThat(classUnderTest.calculatePrice("AirPods")).isEqualTo(new BigDecimal("99.99")); + org.assertj.core.api.Assertions.assertThat(classUnderTest.calculatePrice("AirPods")) + .isEqualTo(new BigDecimal("99.99")); verify(mockedProductReporter).notify("AirPods"); } - } diff --git a/spring-boot-testing-tips-and-tricks/src/test/java/de/rieckpil/blog/SecondDefinedPortApplicationTest.java b/spring-boot-testing-tips-and-tricks/src/test/java/de/rieckpil/blog/SecondDefinedPortApplicationTest.java index af321499..79fb7a68 100644 --- a/spring-boot-testing-tips-and-tricks/src/test/java/de/rieckpil/blog/SecondDefinedPortApplicationTest.java +++ b/spring-boot-testing-tips-and-tricks/src/test/java/de/rieckpil/blog/SecondDefinedPortApplicationTest.java @@ -1,22 +1,20 @@ package de.rieckpil.blog; +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment; + import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.boot.web.server.LocalServerPort; - -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.test.web.server.LocalServerPort; @Disabled("Will fail because other IT already launches on the defined port") @SpringBootTest(webEnvironment = WebEnvironment.DEFINED_PORT) class SecondDefinedPortApplicationTest { - @LocalServerPort - private Integer port; + @LocalServerPort private Integer port; - @MockBean - private CustomerService customerService; + @MockBean private CustomerService customerService; @Test void accessApplication() { diff --git a/spring-boot-testing-tips-and-tricks/src/test/java/de/rieckpil/blog/VerboseLoggingServiceTest.java b/spring-boot-testing-tips-and-tricks/src/test/java/de/rieckpil/blog/VerboseLoggingServiceTest.java index d400d09d..58fbb6ac 100644 --- a/spring-boot-testing-tips-and-tricks/src/test/java/de/rieckpil/blog/VerboseLoggingServiceTest.java +++ b/spring-boot-testing-tips-and-tricks/src/test/java/de/rieckpil/blog/VerboseLoggingServiceTest.java @@ -1,17 +1,16 @@ package de.rieckpil.blog; +import static org.junit.jupiter.api.Assertions.assertLinesMatch; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.Arrays; +import java.util.List; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.boot.test.system.CapturedOutput; import org.springframework.boot.test.system.OutputCaptureExtension; -import java.util.Arrays; -import java.util.List; - -import static org.junit.jupiter.api.Assertions.assertLinesMatch; -import static org.junit.jupiter.api.Assertions.assertTrue; - @ExtendWith(OutputCaptureExtension.class) class VerboseLoggingServiceTest { @@ -23,8 +22,8 @@ void verifySystemOut(CapturedOutput capturedOutput) { cut.notify("Hello World!"); assertLinesMatch( - List.of("Hello World!", ".*VerboseLoggingService - Hello World!"), - Arrays.asList(capturedOutput.getOut().split("\n"))); + List.of("Hello World!", ".*VerboseLoggingService - Hello World!"), + Arrays.asList(capturedOutput.getOut().split("\n"))); assertTrue(capturedOutput.getErr().contains("Error"), "System.err did not contain message"); } diff --git a/spring-boot-testing-tips-and-tricks/src/test/java/de/rieckpil/blog/extension/ApplicationIT.java b/spring-boot-testing-tips-and-tricks/src/test/java/de/rieckpil/blog/extension/ApplicationIT.java index 4ad67d15..b1525ff7 100644 --- a/spring-boot-testing-tips-and-tricks/src/test/java/de/rieckpil/blog/extension/ApplicationIT.java +++ b/spring-boot-testing-tips-and-tricks/src/test/java/de/rieckpil/blog/extension/ApplicationIT.java @@ -1,14 +1,14 @@ package de.rieckpil.blog.extension; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment; + import de.rieckpil.blog.CustomerService; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.core.env.Environment; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment; - @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) class ApplicationIT { @@ -18,8 +18,8 @@ class ApplicationIT { @Test void needsEnvironmentBeanToVerifySomething( - @Autowired Environment environment // resolved via the SpringExtension - ) { + @Autowired Environment environment // resolved via the SpringExtension + ) { assertNotNull(environment); } } diff --git a/spring-boot-testing-tips-and-tricks/src/test/java/de/rieckpil/blog/extension/RedundantApplicationIT.java b/spring-boot-testing-tips-and-tricks/src/test/java/de/rieckpil/blog/extension/RedundantApplicationIT.java index 0a936b4c..dc985716 100644 --- a/spring-boot-testing-tips-and-tricks/src/test/java/de/rieckpil/blog/extension/RedundantApplicationIT.java +++ b/spring-boot-testing-tips-and-tricks/src/test/java/de/rieckpil/blog/extension/RedundantApplicationIT.java @@ -1,5 +1,8 @@ package de.rieckpil.blog.extension; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment; + import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; @@ -7,15 +10,11 @@ import org.springframework.context.ApplicationContext; import org.springframework.test.context.junit.jupiter.SpringExtension; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment; - @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) @ExtendWith(SpringExtension.class) // can be removed class RedundantApplicationIT { - @Autowired - ApplicationContext context; + @Autowired ApplicationContext context; @Test void shouldStartContext() { diff --git a/spring-boot-thymeleaf-testing/src/main/java/de/rieckpil/Application.java b/spring-boot-thymeleaf-testing/src/main/java/de/rieckpil/Application.java index de296439..22638758 100644 --- a/spring-boot-thymeleaf-testing/src/main/java/de/rieckpil/Application.java +++ b/spring-boot-thymeleaf-testing/src/main/java/de/rieckpil/Application.java @@ -9,5 +9,4 @@ public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } - } diff --git a/spring-boot-thymeleaf-testing/src/main/java/de/rieckpil/CustomerController.java b/spring-boot-thymeleaf-testing/src/main/java/de/rieckpil/CustomerController.java index bfff75fa..42b1e41b 100644 --- a/spring-boot-thymeleaf-testing/src/main/java/de/rieckpil/CustomerController.java +++ b/spring-boot-thymeleaf-testing/src/main/java/de/rieckpil/CustomerController.java @@ -4,13 +4,13 @@ import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; - import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; + @Controller @RequestMapping("/customers") public class CustomerController { @@ -28,9 +28,7 @@ public String getCustomerView(Model model) { @PostMapping public String createCustomer( - @Valid CustomerFormObject customerFormObject, - BindingResult bindingResult, - Model model) { + @Valid CustomerFormObject customerFormObject, BindingResult bindingResult, Model model) { if (bindingResult.hasErrors()) { model.addAttribute("customers", CUSTOMERS); @@ -42,14 +40,14 @@ public String createCustomer( return "redirect:/customers"; } - public record Customer( - String name, - String number, - String email, - LocalDateTime createdAt) { + public record Customer(String name, String number, String email, LocalDateTime createdAt) { public static Customer from(CustomerFormObject customerFormObject) { - return new Customer(customerFormObject.getName(), customerFormObject.getNumber(), customerFormObject.getEmail(), LocalDateTime.now()); + return new Customer( + customerFormObject.getName(), + customerFormObject.getNumber(), + customerFormObject.getEmail(), + LocalDateTime.now()); } } } diff --git a/spring-boot-thymeleaf-testing/src/main/java/de/rieckpil/CustomerFormObject.java b/spring-boot-thymeleaf-testing/src/main/java/de/rieckpil/CustomerFormObject.java index 94232a90..6e2d3182 100644 --- a/spring-boot-thymeleaf-testing/src/main/java/de/rieckpil/CustomerFormObject.java +++ b/spring-boot-thymeleaf-testing/src/main/java/de/rieckpil/CustomerFormObject.java @@ -2,17 +2,14 @@ import jakarta.validation.constraints.Email; import jakarta.validation.constraints.NotEmpty; + public class CustomerFormObject { - @NotEmpty - private String name; + @NotEmpty private String name; - @NotEmpty - private String number; + @NotEmpty private String number; - @Email - @NotEmpty - private String email; + @Email @NotEmpty private String email; public String getName() { return name; diff --git a/spring-boot-thymeleaf-testing/src/main/java/de/rieckpil/SecurityConfig.java b/spring-boot-thymeleaf-testing/src/main/java/de/rieckpil/SecurityConfig.java index 98179380..85d26019 100644 --- a/spring-boot-thymeleaf-testing/src/main/java/de/rieckpil/SecurityConfig.java +++ b/spring-boot-thymeleaf-testing/src/main/java/de/rieckpil/SecurityConfig.java @@ -1,27 +1,30 @@ package de.rieckpil; +import static org.springframework.security.config.Customizer.withDefaults; + import org.springframework.boot.autoconfigure.security.servlet.PathRequest; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.security.config.Customizer; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.web.SecurityFilterChain; -import static org.springframework.security.config.Customizer.withDefaults; - @Configuration public class SecurityConfig { @Bean public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception { - httpSecurity.authorizeHttpRequests( - authorize -> - authorize.requestMatchers("/customers").permitAll() - .requestMatchers(PathRequest.toStaticResources().atCommonLocations()).permitAll() - .anyRequest().authenticated() - ) - .formLogin(withDefaults()) - .csrf(withDefaults()); + httpSecurity + .authorizeHttpRequests( + authorize -> + authorize + .requestMatchers("/customers") + .permitAll() + .requestMatchers(PathRequest.toStaticResources().atCommonLocations()) + .permitAll() + .anyRequest() + .authenticated()) + .formLogin(withDefaults()) + .csrf(withDefaults()); return httpSecurity.build(); } diff --git a/spring-boot-thymeleaf-testing/src/test/java/de/rieckpil/AdminControllerTest.java b/spring-boot-thymeleaf-testing/src/test/java/de/rieckpil/AdminControllerTest.java index d599ce7d..b923252c 100644 --- a/spring-boot-thymeleaf-testing/src/test/java/de/rieckpil/AdminControllerTest.java +++ b/spring-boot-thymeleaf-testing/src/test/java/de/rieckpil/AdminControllerTest.java @@ -1,64 +1,45 @@ package de.rieckpil; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.model; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view; + import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.context.annotation.Import; import org.springframework.security.test.context.support.WithMockUser; -import org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestBuilders; import org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors; import org.springframework.test.web.servlet.MockMvc; -import org.springframework.test.web.servlet.MvcResult; - -import static org.hamcrest.Matchers.is; -import static org.junit.jupiter.api.Assertions.*; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.ArgumentMatchers.*; -import static org.mockito.Mockito.when; -import static org.mockito.Mockito.verify; -import static org.springframework.http.HttpHeaders.ACCEPT; -import static org.springframework.http.MediaType.APPLICATION_JSON; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.model; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view; @Import(SecurityConfig.class) @WebMvcTest(AdminController.class) class AdminControllerTest { - @Autowired - private MockMvc mockMvc; + @Autowired private MockMvc mockMvc; @Test void shouldRedirectAnonymousUserToLogin() throws Exception { - this.mockMvc - .perform(get("/admin")) - .andExpect(status().is3xxRedirection()); + this.mockMvc.perform(get("/admin")).andExpect(status().is3xxRedirection()); } @Test @WithMockUser(username = "duke") void shouldAllowAccessForAuthenticatedUser() throws Exception { this.mockMvc - .perform(get("/admin")) - .andExpect(status().isOk()) - .andExpect(view().name("admin")) - .andExpect(model().attributeExists("message")); + .perform(get("/admin")) + .andExpect(status().isOk()) + .andExpect(view().name("admin")) + .andExpect(model().attributeExists("message")); } @Test void shouldAllowAccessForAuthenticatedUserAlternative() throws Exception { this.mockMvc - .perform(get("/admin") - .with(SecurityMockMvcRequestPostProcessors.user("mike"))) - .andExpect(status().isOk()) - .andExpect(view().name("admin")) - .andExpect(model().attributeExists("message")); + .perform(get("/admin").with(SecurityMockMvcRequestPostProcessors.user("mike"))) + .andExpect(status().isOk()) + .andExpect(view().name("admin")) + .andExpect(model().attributeExists("message")); } } diff --git a/spring-boot-thymeleaf-testing/src/test/java/de/rieckpil/ApplicationTest.java b/spring-boot-thymeleaf-testing/src/test/java/de/rieckpil/ApplicationTest.java index 9b193c44..64405fe5 100644 --- a/spring-boot-thymeleaf-testing/src/test/java/de/rieckpil/ApplicationTest.java +++ b/spring-boot-thymeleaf-testing/src/test/java/de/rieckpil/ApplicationTest.java @@ -7,6 +7,5 @@ class ApplicationTest { @Test - void contextLoads() { - } + void contextLoads() {} } diff --git a/spring-boot-thymeleaf-testing/src/test/java/de/rieckpil/CustomerControllerHtmlUnitTest.java b/spring-boot-thymeleaf-testing/src/test/java/de/rieckpil/CustomerControllerHtmlUnitTest.java index 11843df9..af44f8f2 100644 --- a/spring-boot-thymeleaf-testing/src/test/java/de/rieckpil/CustomerControllerHtmlUnitTest.java +++ b/spring-boot-thymeleaf-testing/src/test/java/de/rieckpil/CustomerControllerHtmlUnitTest.java @@ -1,7 +1,6 @@ package de.rieckpil; -import java.net.URL; -import java.util.List; +import static org.assertj.core.api.Assertions.assertThat; import com.gargoylesoftware.htmlunit.WebClient; import com.gargoylesoftware.htmlunit.html.HtmlEmailInput; @@ -9,29 +8,19 @@ import com.gargoylesoftware.htmlunit.html.HtmlTable; import com.gargoylesoftware.htmlunit.html.HtmlTableRow; import com.gargoylesoftware.htmlunit.html.HtmlTextInput; -import com.gargoylesoftware.htmlunit.javascript.host.html.HTMLInputElement; +import java.net.URL; +import java.util.List; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.context.annotation.Import; -import org.springframework.test.web.servlet.MockMvc; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.model; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view; @Import(SecurityConfig.class) @WebMvcTest(CustomerController.class) class CustomerControllerHtmlUnitTest { - @Autowired - private WebClient webClient; + @Autowired private WebClient webClient; @BeforeEach void setup() { @@ -52,8 +41,7 @@ void shouldCreateAndDisplayNewCustomer() throws Exception { assertThat(pageAfterFormSubmit.getUrl()).isEqualTo(new URL("http://localhost:8080/customers")); - HtmlTable pendingSubscribersTable = pageAfterFormSubmit - .getHtmlElementById("customer-list"); + HtmlTable pendingSubscribersTable = pageAfterFormSubmit.getHtmlElementById("customer-list"); List rows = pendingSubscribersTable.getRows(); @@ -64,12 +52,13 @@ void shouldCreateAndDisplayNewCustomer() throws Exception { assertThat(headerRow.getCell(3).asNormalizedText()).isEqualTo("Email"); assertThat(headerRow.getCell(4).asNormalizedText()).isEqualTo("Created At"); - HtmlTableRow createdRow = rows.stream().filter( - row -> row.getCell(2).asNormalizedText().equals("C0123") - ).findFirst() - .get(); + HtmlTableRow createdRow = + rows.stream() + .filter(row -> row.getCell(2).asNormalizedText().equals("C0123")) + .findFirst() + .get(); - assertThat(createdRow.getCell(0).asNormalizedText()).isEqualTo("1"); + assertThat(createdRow.getCell(0).asNormalizedText()).isNotBlank(); assertThat(createdRow.getCell(1).asNormalizedText()).isEqualTo("duke"); assertThat(createdRow.getCell(2).asNormalizedText()).isEqualTo("C0123"); assertThat(createdRow.getCell(3).asNormalizedText()).isEqualTo("duke@java.org"); diff --git a/spring-boot-thymeleaf-testing/src/test/java/de/rieckpil/CustomerControllerTest.java b/spring-boot-thymeleaf-testing/src/test/java/de/rieckpil/CustomerControllerTest.java index e6589b7f..32f54263 100644 --- a/spring-boot-thymeleaf-testing/src/test/java/de/rieckpil/CustomerControllerTest.java +++ b/spring-boot-thymeleaf-testing/src/test/java/de/rieckpil/CustomerControllerTest.java @@ -1,73 +1,60 @@ package de.rieckpil; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; -import org.springframework.context.annotation.Import; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.test.web.servlet.MvcResult; - -import static org.hamcrest.Matchers.is; -import static org.junit.jupiter.api.Assertions.*; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.ArgumentMatchers.*; -import static org.mockito.Mockito.when; -import static org.mockito.Mockito.verify; -import static org.springframework.http.HttpHeaders.ACCEPT; -import static org.springframework.http.MediaType.APPLICATION_JSON; import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.model; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.context.annotation.Import; +import org.springframework.test.web.servlet.MockMvc; + @Import(SecurityConfig.class) @WebMvcTest(CustomerController.class) class CustomerControllerTest { - @Autowired - private MockMvc mockMvc; + @Autowired private MockMvc mockMvc; @Test void shouldAllowAccessForAnonymousUser() throws Exception { this.mockMvc - .perform(get("/customers")) - .andExpect(status().isOk()) - .andExpect(view().name("customers")) - .andExpect(model().attributeExists("customers")) - .andExpect(model().attributeExists("customerFormObject")); + .perform(get("/customers")) + .andExpect(status().isOk()) + .andExpect(view().name("customers")) + .andExpect(model().attributeExists("customers")) + .andExpect(model().attributeExists("customerFormObject")); } @Test void shouldRejectInvalidPayloadWhenCreatingCustomer() throws Exception { this.mockMvc - .perform(post("/customers") - .param("name", "duke") - .param("number", "C0124") - .param("email", "notanemail.io") - .with(csrf())) - .andExpect(status().isOk()) - .andExpect(view().name("customers")) - .andExpect(model().hasErrors()) - .andExpect(model().attributeHasErrors("customerFormObject")); + .perform( + post("/customers") + .param("name", "duke") + .param("number", "C0124") + .param("email", "notanemail.io") + .with(csrf())) + .andExpect(status().isOk()) + .andExpect(view().name("customers")) + .andExpect(model().hasErrors()) + .andExpect(model().attributeHasErrors("customerFormObject")); } @Test void shouldCreateNewCustomer() throws Exception { this.mockMvc - .perform(post("/customers") - .param("name", "duke") - .param("number", "C0124") - .param("email", "duke@java.io") - .with(csrf())) - .andExpect(status().is3xxRedirection()) - .andExpect(header().string("Location", "/customers")); + .perform( + post("/customers") + .param("name", "duke") + .param("number", "C0124") + .param("email", "duke@java.io") + .with(csrf())) + .andExpect(status().is3xxRedirection()) + .andExpect(header().string("Location", "/customers")); } } diff --git a/spring-boot-uploading-and-downloading-files-with-react/.java-version b/spring-boot-uploading-and-downloading-files-with-react/.java-version deleted file mode 100644 index 2dbc24b3..00000000 --- a/spring-boot-uploading-and-downloading-files-with-react/.java-version +++ /dev/null @@ -1 +0,0 @@ -11.0 diff --git a/spring-boot-uploading-and-downloading-files-with-react/frontend/package-lock.json b/spring-boot-uploading-and-downloading-files-with-react/frontend/package-lock.json index 20fb6387..ca7876a5 100644 --- a/spring-boot-uploading-and-downloading-files-with-react/frontend/package-lock.json +++ b/spring-boot-uploading-and-downloading-files-with-react/frontend/package-lock.json @@ -5,6 +5,7 @@ "requires": true, "packages": { "": { + "name": "frontend", "version": "0.1.0", "dependencies": { "react": "^17.0.2", diff --git a/spring-boot-uploading-and-downloading-files-with-react/pom.xml b/spring-boot-uploading-and-downloading-files-with-react/pom.xml index 2faa781d..f5b02bc6 100644 --- a/spring-boot-uploading-and-downloading-files-with-react/pom.xml +++ b/spring-boot-uploading-and-downloading-files-with-react/pom.xml @@ -1,24 +1,19 @@ - + 4.0.0 + + de.rieckpil.blog + blog-parent + 0.0.1-SNAPSHOT + ../pom.xml + + de.rieckpil.learning spring-boot-uploading-and-downloading-files-with-react 0.0.1-SNAPSHOT jar - - org.springframework.boot - spring-boot-starter-parent - 2.5.0 - - - - - 11 - - org.springframework.boot @@ -49,24 +44,24 @@ app - ${project.basedir}/frontend/build - false public/ + false + ${project.basedir}/frontend/build - ${project.basedir}/src/main/resources false + ${project.basedir}/src/main/resources - - org.springframework.boot - spring-boot-maven-plugin - com.github.eirslett frontend-maven-plugin - 1.12.0 + 1.15.0 + + frontend + v16.20.0 + install node and npm @@ -99,10 +94,6 @@ - - frontend - v15.14.0 - diff --git a/spring-boot-uploading-and-downloading-files-with-react/src/main/java/de/rieckpil/blog/FileBoundary.java b/spring-boot-uploading-and-downloading-files-with-react/src/main/java/de/rieckpil/blog/FileBoundary.java index b9d7a504..28149a41 100644 --- a/spring-boot-uploading-and-downloading-files-with-react/src/main/java/de/rieckpil/blog/FileBoundary.java +++ b/spring-boot-uploading-and-downloading-files-with-react/src/main/java/de/rieckpil/blog/FileBoundary.java @@ -1,5 +1,9 @@ package de.rieckpil.blog; +import jakarta.validation.constraints.NotNull; +import java.io.IOException; +import java.net.URI; +import java.util.concurrent.ThreadLocalRandom; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; @@ -8,14 +12,11 @@ import org.springframework.web.multipart.MultipartFile; import org.springframework.web.servlet.support.ServletUriComponentsBuilder; -import javax.validation.constraints.NotNull; -import java.io.IOException; -import java.net.URI; -import java.util.concurrent.ThreadLocalRandom; - @RestController @RequestMapping("/api/files") -@CrossOrigin(value = {"*"}, exposedHeaders = {"Content-Disposition"}) +@CrossOrigin( + value = {"*"}, + exposedHeaders = {"Content-Disposition"}) public class FileBoundary { private final FileEntityRepository fileEntityRepository; @@ -50,16 +51,18 @@ public ResponseEntity getRandomFile() { } @PostMapping - public ResponseEntity uploadNewFile(@NotNull @RequestParam("file") MultipartFile multipartFile) throws IOException { + public ResponseEntity uploadNewFile( + @NotNull @RequestParam("file") MultipartFile multipartFile) throws IOException { - FileEntity fileEntity = new FileEntity(multipartFile.getOriginalFilename(), multipartFile.getContentType(), - multipartFile.getBytes()); + FileEntity fileEntity = + new FileEntity( + multipartFile.getOriginalFilename(), + multipartFile.getContentType(), + multipartFile.getBytes()); fileEntityRepository.save(fileEntity); URI location = ServletUriComponentsBuilder.fromCurrentRequest().build().toUri(); return ResponseEntity.created(location).build(); - } - } diff --git a/spring-boot-uploading-and-downloading-files-with-react/src/main/java/de/rieckpil/blog/FileEntity.java b/spring-boot-uploading-and-downloading-files-with-react/src/main/java/de/rieckpil/blog/FileEntity.java index f7469267..a56680cb 100644 --- a/spring-boot-uploading-and-downloading-files-with-react/src/main/java/de/rieckpil/blog/FileEntity.java +++ b/spring-boot-uploading-and-downloading-files-with-react/src/main/java/de/rieckpil/blog/FileEntity.java @@ -1,6 +1,6 @@ package de.rieckpil.blog; -import javax.persistence.*; +import jakarta.persistence.*; @Entity public class FileEntity { @@ -13,11 +13,9 @@ public class FileEntity { private String contentType; - @Lob - private byte[] data; + @Lob private byte[] data; - public FileEntity() { - } + public FileEntity() {} public FileEntity(String fileName, String contentType, byte[] data) { this.fileName = fileName; diff --git a/spring-boot-uploading-and-downloading-files-with-react/src/main/java/de/rieckpil/blog/FileEntityRepository.java b/spring-boot-uploading-and-downloading-files-with-react/src/main/java/de/rieckpil/blog/FileEntityRepository.java index 1255bbe7..14fff784 100644 --- a/spring-boot-uploading-and-downloading-files-with-react/src/main/java/de/rieckpil/blog/FileEntityRepository.java +++ b/spring-boot-uploading-and-downloading-files-with-react/src/main/java/de/rieckpil/blog/FileEntityRepository.java @@ -2,5 +2,4 @@ import org.springframework.data.jpa.repository.JpaRepository; -public interface FileEntityRepository extends JpaRepository { -} +public interface FileEntityRepository extends JpaRepository {} diff --git a/spring-boot-uploading-and-downloading-files-with-react/src/test/java/de/rieckpil/blog/DemoApplicationTests.java b/spring-boot-uploading-and-downloading-files-with-react/src/test/java/de/rieckpil/blog/DemoApplicationTests.java index a01bb6c2..ca700edd 100644 --- a/spring-boot-uploading-and-downloading-files-with-react/src/test/java/de/rieckpil/blog/DemoApplicationTests.java +++ b/spring-boot-uploading-and-downloading-files-with-react/src/test/java/de/rieckpil/blog/DemoApplicationTests.java @@ -1,16 +1,11 @@ package de.rieckpil.blog; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit.jupiter.SpringExtension; -@ExtendWith(SpringExtension.class) @SpringBootTest -public class DemoApplicationTests { - - @Test - public void contextLoads() { - } +class DemoApplicationTests { + @Test + void contextLoads() {} } diff --git a/spring-boot-web-mvc-testing/src/main/java/de/rieckpil/blog/Application.java b/spring-boot-web-mvc-testing/src/main/java/de/rieckpil/blog/Application.java index bd5e4c56..6511f3c1 100644 --- a/spring-boot-web-mvc-testing/src/main/java/de/rieckpil/blog/Application.java +++ b/spring-boot-web-mvc-testing/src/main/java/de/rieckpil/blog/Application.java @@ -9,5 +9,4 @@ public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } - } diff --git a/spring-boot-web-mvc-testing/src/main/java/de/rieckpil/blog/LoggingContextFilter.java b/spring-boot-web-mvc-testing/src/main/java/de/rieckpil/blog/LoggingContextFilter.java index e8d14ef8..d0f037f7 100644 --- a/spring-boot-web-mvc-testing/src/main/java/de/rieckpil/blog/LoggingContextFilter.java +++ b/spring-boot-web-mvc-testing/src/main/java/de/rieckpil/blog/LoggingContextFilter.java @@ -1,4 +1,3 @@ package de.rieckpil.blog; -public class LoggingContextFilter { -} +public class LoggingContextFilter {} diff --git a/spring-boot-web-mvc-testing/src/main/java/de/rieckpil/blog/WebMvcConfig.java b/spring-boot-web-mvc-testing/src/main/java/de/rieckpil/blog/WebMvcConfig.java index d6588042..f988b01c 100644 --- a/spring-boot-web-mvc-testing/src/main/java/de/rieckpil/blog/WebMvcConfig.java +++ b/spring-boot-web-mvc-testing/src/main/java/de/rieckpil/blog/WebMvcConfig.java @@ -16,7 +16,8 @@ public WebMvcConfig(@Value("${valid-api-key}") String validApiKey) { @Override public void addInterceptors(InterceptorRegistry registry) { - registry.addInterceptor(new WebhookAuthorizationHandlerInterceptor(validApiKey)) - .addPathPatterns("/webhooks/**"); + registry + .addInterceptor(new WebhookAuthorizationHandlerInterceptor(validApiKey)) + .addPathPatterns("/webhooks/**"); } } diff --git a/spring-boot-web-mvc-testing/src/main/java/de/rieckpil/blog/WebSecurityConfig.java b/spring-boot-web-mvc-testing/src/main/java/de/rieckpil/blog/WebSecurityConfig.java index 02fa35c1..fb2aa314 100644 --- a/spring-boot-web-mvc-testing/src/main/java/de/rieckpil/blog/WebSecurityConfig.java +++ b/spring-boot-web-mvc-testing/src/main/java/de/rieckpil/blog/WebSecurityConfig.java @@ -13,11 +13,13 @@ public class WebSecurityConfig { @Bean public SecurityFilterChain configure(HttpSecurity http) throws Exception { http.authorizeRequests( - authorizeRequests -> - authorizeRequests.requestMatchers(HttpMethod.POST, "/webhooks/orders").permitAll() - .anyRequest().authenticated() - ) - .csrf(AbstractHttpConfigurer::disable); + authorizeRequests -> + authorizeRequests + .requestMatchers(HttpMethod.POST, "/webhooks/orders") + .permitAll() + .anyRequest() + .authenticated()) + .csrf(AbstractHttpConfigurer::disable); return http.build(); } diff --git a/spring-boot-web-mvc-testing/src/main/java/de/rieckpil/blog/WebhookAuthorizationHandlerInterceptor.java b/spring-boot-web-mvc-testing/src/main/java/de/rieckpil/blog/WebhookAuthorizationHandlerInterceptor.java index 1365001d..c9513582 100644 --- a/spring-boot-web-mvc-testing/src/main/java/de/rieckpil/blog/WebhookAuthorizationHandlerInterceptor.java +++ b/spring-boot-web-mvc-testing/src/main/java/de/rieckpil/blog/WebhookAuthorizationHandlerInterceptor.java @@ -2,7 +2,6 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.servlet.HandlerInterceptor; @@ -11,14 +10,16 @@ public class WebhookAuthorizationHandlerInterceptor implements HandlerIntercepto private final String validApiKey; - private static final Logger LOG = LoggerFactory.getLogger(WebhookAuthorizationHandlerInterceptor.class); + private static final Logger LOG = + LoggerFactory.getLogger(WebhookAuthorizationHandlerInterceptor.class); public WebhookAuthorizationHandlerInterceptor(String validApiKey) { this.validApiKey = validApiKey; } @Override - public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) + throws Exception { String apiKey = request.getHeader("X-API-KEY"); LOG.debug("Incoming X-API-KEY header for accessing a webhook: '{}'", apiKey); diff --git a/spring-boot-web-mvc-testing/src/test/java/de/rieckpil/blog/ApplicationTest.java b/spring-boot-web-mvc-testing/src/test/java/de/rieckpil/blog/ApplicationTest.java index 779b3054..b6751e0d 100644 --- a/spring-boot-web-mvc-testing/src/test/java/de/rieckpil/blog/ApplicationTest.java +++ b/spring-boot-web-mvc-testing/src/test/java/de/rieckpil/blog/ApplicationTest.java @@ -3,15 +3,9 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; -import static org.springframework.http.MediaType.APPLICATION_JSON; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - @SpringBootTest class ApplicationTest { @Test - void contextLoads() { - } - + void contextLoads() {} } diff --git a/spring-boot-web-mvc-testing/src/test/java/de/rieckpil/blog/WebhookAuthorizationHandlerInterceptorTest.java b/spring-boot-web-mvc-testing/src/test/java/de/rieckpil/blog/WebhookAuthorizationHandlerInterceptorTest.java index 3c13e7c7..8de51c81 100644 --- a/spring-boot-web-mvc-testing/src/test/java/de/rieckpil/blog/WebhookAuthorizationHandlerInterceptorTest.java +++ b/spring-boot-web-mvc-testing/src/test/java/de/rieckpil/blog/WebhookAuthorizationHandlerInterceptorTest.java @@ -1,20 +1,19 @@ package de.rieckpil.blog; +import static org.assertj.core.api.Assertions.assertThat; + import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; - import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; -import static org.assertj.core.api.Assertions.assertThat; - class WebhookAuthorizationHandlerInterceptorTest { private WebhookAuthorizationHandlerInterceptor cut; - private final static String VALID_TEST_API_KEY = "test400"; + private static final String VALID_TEST_API_KEY = "test400"; @BeforeEach void setUp() { @@ -29,10 +28,8 @@ void shouldBlockRequestWithWhenHeaderIsMissing() throws Exception { boolean result = cut.preHandle(httpServletRequest, httpServletResponse, null); - assertThat(result) - .isFalse(); + assertThat(result).isFalse(); - assertThat(httpServletResponse.getStatus()) - .isEqualTo(403); + assertThat(httpServletResponse.getStatus()).isEqualTo(403); } } diff --git a/spring-boot-web-mvc-testing/src/test/java/de/rieckpil/blog/WebhookControllerTest.java b/spring-boot-web-mvc-testing/src/test/java/de/rieckpil/blog/WebhookControllerTest.java index 30b6838e..60988fe9 100644 --- a/spring-boot-web-mvc-testing/src/test/java/de/rieckpil/blog/WebhookControllerTest.java +++ b/spring-boot-web-mvc-testing/src/test/java/de/rieckpil/blog/WebhookControllerTest.java @@ -1,63 +1,62 @@ package de.rieckpil.blog; +import static org.springframework.http.MediaType.APPLICATION_JSON; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.context.annotation.Import; import org.springframework.test.web.servlet.MockMvc; -import static org.springframework.http.MediaType.APPLICATION_JSON; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - @Import(WebSecurityConfig.class) @WebMvcTest(value = WebhookController.class, properties = "valid-api-key=test42") class WebhookControllerTest { - @Autowired - private MockMvc mockMvc; + @Autowired private MockMvc mockMvc; @Test void shouldForbidAccessWithMissingApiKey() throws Exception { this.mockMvc - .perform(post("/webhooks/orders") - .contentType(APPLICATION_JSON) - .content(""" + .perform( + post("/webhooks/orders") + .contentType(APPLICATION_JSON) + .content(""" { "orderId": 42 } - """) - ) - .andExpect(status().isForbidden()); + """)) + .andExpect(status().isForbidden()); } @Test void shouldForbidAccessWithInvalidApiKey() throws Exception { this.mockMvc - .perform(post("/webhooks/orders") - .header("X-API-KEY", "invalid42") - .contentType(APPLICATION_JSON) - .content(""" + .perform( + post("/webhooks/orders") + .header("X-API-KEY", "invalid42") + .contentType(APPLICATION_JSON) + .content(""" { "orderId": 42 } - """) - ) - .andExpect(status().isForbidden()); + """)) + .andExpect(status().isForbidden()); } @Test void shouldAllowAccessWithValidApiKey() throws Exception { this.mockMvc - .perform(post("/webhooks/orders") - .header("X-API-KEY", "test42") - .contentType(APPLICATION_JSON) - .content(""" + .perform( + post("/webhooks/orders") + .header("X-API-KEY", "test42") + .contentType(APPLICATION_JSON) + .content(""" { "orderId": 42 } - """) - ) - .andExpect(status().isNoContent()); + """)) + .andExpect(status().isNoContent()); } } diff --git a/spring-boot-with-kotlin/pom.xml b/spring-boot-with-kotlin/pom.xml index 2bb3aae5..875cf93a 100644 --- a/spring-boot-with-kotlin/pom.xml +++ b/spring-boot-with-kotlin/pom.xml @@ -1,26 +1,19 @@ - + 4.0.0 - org.springframework.boot - spring-boot-starter-parent - 2.5.0 - + de.rieckpil.blog + blog-parent + 0.0.1-SNAPSHOT + ../pom.xml - de.rieckpil.blog spring-boot-with-kotlin 0.0.1-SNAPSHOT spring-boot-with-kotlin Template for Spring Boot applications with Kotlin - - 11 - 1.5.0 - - org.springframework.boot @@ -76,16 +69,14 @@ - src/main/kotlin - src/test/kotlin org.springframework.boot spring-boot-maven-plugin - kotlin-maven-plugin org.jetbrains.kotlin + kotlin-maven-plugin -Xjsr305=strict @@ -117,48 +108,48 @@ org.apache.maven.plugins maven-antrun-plugin - 1.8 + 3.1.0 + + + com.pinterest.ktlint + ktlint-cli + 1.1.1 + + ktlint + + run + validate - - + + - - run - ktlint-format + + run + - - - + + + - - run - - - - com.pinterest - ktlint - 0.41.0 - - + src/main/kotlin + src/test/kotlin diff --git a/spring-boot-with-kotlin/src/main/kotlin/de.rieckpil.blog/ApiController.kt b/spring-boot-with-kotlin/src/main/kotlin/de.rieckpil.blog/ApiController.kt index 29085e26..d0d89855 100644 --- a/spring-boot-with-kotlin/src/main/kotlin/de.rieckpil.blog/ApiController.kt +++ b/spring-boot-with-kotlin/src/main/kotlin/de.rieckpil.blog/ApiController.kt @@ -11,16 +11,16 @@ import org.springframework.web.reactive.function.client.WebClient @RequestMapping("/api") class ApiController( val jsonPlaceHolderWebClient: WebClient, - val personRepository: PersonRepository + val personRepository: PersonRepository, ) { - @GetMapping(value = ["/todos"], produces = [MediaType.APPLICATION_JSON_VALUE]) - fun getAllTodos() = jsonPlaceHolderWebClient - .get() - .uri("/todos") - .retrieve() - .bodyToMono(ArrayNode::class.java) - .block() + fun getAllTodos() = + jsonPlaceHolderWebClient + .get() + .uri("/todos") + .retrieve() + .bodyToMono(ArrayNode::class.java) + .block() @GetMapping(value = ["/persons"], produces = [MediaType.APPLICATION_JSON_VALUE]) fun getAllPersons(): List = personRepository.findAll() diff --git a/spring-boot-with-kotlin/src/main/kotlin/de.rieckpil.blog/Application.kt b/spring-boot-with-kotlin/src/main/kotlin/de.rieckpil.blog/Application.kt index 557955b7..50cf101c 100644 --- a/spring-boot-with-kotlin/src/main/kotlin/de.rieckpil.blog/Application.kt +++ b/spring-boot-with-kotlin/src/main/kotlin/de.rieckpil.blog/Application.kt @@ -15,25 +15,33 @@ fun main(args: Array) { @Component class PersonInitializer( - private val personRepository: PersonRepository + private val personRepository: PersonRepository, ) : CommandLineRunner { - - override fun run( - vararg args: String? - ) { - - val personOne = Person( - null, "Mike", "Kotlin", "mk90", - LocalDate.of(1990, 1, 1) - ) - val personTwo = Person( - null, "Java", "Duke", "jduke", - LocalDate.of(1995, 1, 1) - ) - val personThree = Person( - null, "Andy", "Fresh", "afresh", - LocalDate.of(2000, 1, 1) - ) + override fun run(vararg args: String?) { + val personOne = + Person( + null, + "Mike", + "Kotlin", + "mk90", + LocalDate.of(1990, 1, 1), + ) + val personTwo = + Person( + null, + "Java", + "Duke", + "jduke", + LocalDate.of(1995, 1, 1), + ) + val personThree = + Person( + null, + "Andy", + "Fresh", + "afresh", + LocalDate.of(2000, 1, 1), + ) personRepository.saveAll(listOf(personOne, personTwo, personThree)) } diff --git a/spring-boot-with-kotlin/src/main/kotlin/de.rieckpil.blog/Person.kt b/spring-boot-with-kotlin/src/main/kotlin/de.rieckpil.blog/Person.kt index abf791b4..4bedaf72 100644 --- a/spring-boot-with-kotlin/src/main/kotlin/de.rieckpil.blog/Person.kt +++ b/spring-boot-with-kotlin/src/main/kotlin/de.rieckpil.blog/Person.kt @@ -1,10 +1,10 @@ package de.rieckpil.blog +import jakarta.persistence.Column +import jakarta.persistence.Entity +import jakarta.persistence.GeneratedValue +import jakarta.persistence.Id import java.time.LocalDate -import javax.persistence.Column -import javax.persistence.Entity -import javax.persistence.GeneratedValue -import javax.persistence.Id @Entity class Person( @@ -12,5 +12,5 @@ class Person( @Column(nullable = false) var firstname: String, @Column(nullable = false) var lastname: String, @Column(unique = true, nullable = false) var username: String, - @Column(nullable = false) var dayOfBirth: LocalDate + @Column(nullable = false) var dayOfBirth: LocalDate, ) diff --git a/spring-boot-with-kotlin/src/main/kotlin/de.rieckpil.blog/WebClientConfig.kt b/spring-boot-with-kotlin/src/main/kotlin/de.rieckpil.blog/WebClientConfig.kt index 4fa31d21..c0679fbe 100644 --- a/spring-boot-with-kotlin/src/main/kotlin/de.rieckpil.blog/WebClientConfig.kt +++ b/spring-boot-with-kotlin/src/main/kotlin/de.rieckpil.blog/WebClientConfig.kt @@ -8,12 +8,12 @@ import org.springframework.web.reactive.function.client.WebClient @Configuration class WebClientConfig { - @Bean - fun jsonPlaceHolderWebClient(builder: WebClient.Builder) = builder - .clone() - .baseUrl("https://jsonplaceholder.typicode.com") - .defaultHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE) - .defaultHeader(HttpHeaders.USER_AGENT, "SpringBootKotlinApplication") - .build() + fun jsonPlaceHolderWebClient(builder: WebClient.Builder) = + builder + .clone() + .baseUrl("https://jsonplaceholder.typicode.com") + .defaultHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE) + .defaultHeader(HttpHeaders.USER_AGENT, "SpringBootKotlinApplication") + .build() } diff --git a/spring-boot-with-kotlin/src/test/kotlin/de/rieckpil/blog/ApiControllerIntegrationTest.kt b/spring-boot-with-kotlin/src/test/kotlin/de/rieckpil/blog/ApiControllerIntegrationTest.kt index 4f713f10..49f46537 100644 --- a/spring-boot-with-kotlin/src/test/kotlin/de/rieckpil/blog/ApiControllerIntegrationTest.kt +++ b/spring-boot-with-kotlin/src/test/kotlin/de/rieckpil/blog/ApiControllerIntegrationTest.kt @@ -9,9 +9,8 @@ import org.springframework.test.web.reactive.server.WebTestClient @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) class ApiControllerIntegrationTest( - @Autowired val webTestClient: WebTestClient + @Autowired val webTestClient: WebTestClient, ) { - @Test fun `should get todos with status code 200`() { this.webTestClient diff --git a/spring-boot-with-kotlin/src/test/kotlin/de/rieckpil/blog/SpringBootWithKotlinApplicationTest.kt b/spring-boot-with-kotlin/src/test/kotlin/de/rieckpil/blog/SpringBootWithKotlinApplicationTest.kt index 5c539c83..12835fa6 100644 --- a/spring-boot-with-kotlin/src/test/kotlin/de/rieckpil/blog/SpringBootWithKotlinApplicationTest.kt +++ b/spring-boot-with-kotlin/src/test/kotlin/de/rieckpil/blog/SpringBootWithKotlinApplicationTest.kt @@ -5,7 +5,6 @@ import org.springframework.boot.test.context.SpringBootTest @SpringBootTest class SpringBootWithKotlinApplicationTest { - @Test fun `Spring context should load`() { } diff --git a/spring-cloud-aws-sqs-testing/pom.xml b/spring-cloud-aws-sqs-testing/pom.xml index 5f137d04..e231ec08 100644 --- a/spring-cloud-aws-sqs-testing/pom.xml +++ b/spring-cloud-aws-sqs-testing/pom.xml @@ -1,28 +1,35 @@ - + 4.0.0 - org.springframework.boot - spring-boot-starter-parent - 2.7.0 - + de.rieckpil.blog + blog-parent + 0.0.1-SNAPSHOT + ../pom.xml - de.rieckpil spring-cloud-aws-sqs-testing 0.0.1-SNAPSHOT spring-cloud-aws-sqs-testing spring-cloud-aws-sqs-testing - 17 - 1.17.2 - 2.4.1 - 4.2.0 + 3.1.0 + + + + io.awspring.cloud + spring-cloud-aws-dependencies + ${spring-cloud-aws.version} + pom + import + + + + org.springframework.boot @@ -34,7 +41,7 @@ io.awspring.cloud - spring-cloud-starter-aws-messaging + spring-cloud-aws-starter-sqs @@ -55,7 +62,6 @@ org.awaitility awaitility - ${awaitility.version} test @@ -70,25 +76,6 @@ - - - - org.testcontainers - testcontainers-bom - ${testcontainers.version} - pom - import - - - io.awspring.cloud - spring-cloud-aws-dependencies - ${spring-cloud-aws.version} - pom - import - - - - diff --git a/spring-cloud-aws-sqs-testing/src/main/java/de/rieckpil/Application.java b/spring-cloud-aws-sqs-testing/src/main/java/de/rieckpil/Application.java index de296439..22638758 100644 --- a/spring-cloud-aws-sqs-testing/src/main/java/de/rieckpil/Application.java +++ b/spring-cloud-aws-sqs-testing/src/main/java/de/rieckpil/Application.java @@ -9,5 +9,4 @@ public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } - } diff --git a/spring-cloud-aws-sqs-testing/src/main/java/de/rieckpil/OrderListener.java b/spring-cloud-aws-sqs-testing/src/main/java/de/rieckpil/OrderListener.java index be9576d9..936bfc68 100644 --- a/spring-cloud-aws-sqs-testing/src/main/java/de/rieckpil/OrderListener.java +++ b/spring-cloud-aws-sqs-testing/src/main/java/de/rieckpil/OrderListener.java @@ -1,15 +1,14 @@ package de.rieckpil; -import java.util.Map; - -import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; -import io.awspring.cloud.messaging.listener.annotation.SqsListener; +import io.awspring.cloud.sqs.annotation.SqsListener; +import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.messaging.handler.annotation.Headers; import org.springframework.messaging.handler.annotation.Payload; -import org.springframework.messaging.support.GenericMessage; import org.springframework.stereotype.Component; @Component @@ -24,12 +23,15 @@ public OrderListener(PurchaseOrderRepository purchaseOrderRepository) { } @SqsListener("${order-queue-name}") - public void processOrder(@Payload ObjectNode payload, @Headers Map payloadHeaders) { - LOG.info("Incoming order payload {} with headers {}", payload, payloadHeaders); + public void processOrder(@Payload String rawPayload, @Headers Map payloadHeaders) + throws JsonProcessingException { + LOG.info("Incoming order payload {} with headers {}", rawPayload, payloadHeaders); + + ObjectNode payload = new ObjectMapper().readValue(rawPayload, ObjectNode.class); PurchaseOrder purchaseOrder = new PurchaseOrder(); - purchaseOrder.setCustomer(payload.get("customer_name").asText()); - purchaseOrder.setAmount(payload.get("order_amount").asLong()); + purchaseOrder.setCustomer(payload.get("customerName").asText()); + purchaseOrder.setAmount(payload.get("orderAmount").asLong()); purchaseOrder.setDelivered(false); purchaseOrderRepository.save(purchaseOrder); diff --git a/spring-cloud-aws-sqs-testing/src/main/java/de/rieckpil/PurchaseOrder.java b/spring-cloud-aws-sqs-testing/src/main/java/de/rieckpil/PurchaseOrder.java index 2c914f89..16715dd5 100644 --- a/spring-cloud-aws-sqs-testing/src/main/java/de/rieckpil/PurchaseOrder.java +++ b/spring-cloud-aws-sqs-testing/src/main/java/de/rieckpil/PurchaseOrder.java @@ -1,15 +1,13 @@ package de.rieckpil; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; @Entity public class PurchaseOrder { - @Id - @GeneratedValue - private Long id; + @Id @GeneratedValue private Long id; private String customer; diff --git a/spring-cloud-aws-sqs-testing/src/main/java/de/rieckpil/PurchaseOrderPayload.java b/spring-cloud-aws-sqs-testing/src/main/java/de/rieckpil/PurchaseOrderPayload.java new file mode 100644 index 00000000..633c6daf --- /dev/null +++ b/spring-cloud-aws-sqs-testing/src/main/java/de/rieckpil/PurchaseOrderPayload.java @@ -0,0 +1,30 @@ +package de.rieckpil; + +public class PurchaseOrderPayload { + + private String customerName; + private Long orderAmount; + + public PurchaseOrderPayload() {} + + public PurchaseOrderPayload(String customerName, Long orderAmount) { + this.customerName = customerName; + this.orderAmount = orderAmount; + } + + public String getCustomerName() { + return customerName; + } + + public void setCustomerName(String customerName) { + this.customerName = customerName; + } + + public Long getOrderAmount() { + return orderAmount; + } + + public void setOrderAmount(Long orderAmount) { + this.orderAmount = orderAmount; + } +} diff --git a/spring-cloud-aws-sqs-testing/src/main/java/de/rieckpil/PurchaseOrderRepository.java b/spring-cloud-aws-sqs-testing/src/main/java/de/rieckpil/PurchaseOrderRepository.java index 647f7789..017048fa 100644 --- a/spring-cloud-aws-sqs-testing/src/main/java/de/rieckpil/PurchaseOrderRepository.java +++ b/spring-cloud-aws-sqs-testing/src/main/java/de/rieckpil/PurchaseOrderRepository.java @@ -1,7 +1,5 @@ package de.rieckpil; - import org.springframework.data.jpa.repository.JpaRepository; -public interface PurchaseOrderRepository extends JpaRepository { -} +public interface PurchaseOrderRepository extends JpaRepository {} diff --git a/spring-cloud-aws-sqs-testing/src/main/resources/application.properties b/spring-cloud-aws-sqs-testing/src/main/resources/application.properties index 36dbd143..e69de29b 100644 --- a/spring-cloud-aws-sqs-testing/src/main/resources/application.properties +++ b/spring-cloud-aws-sqs-testing/src/main/resources/application.properties @@ -1 +0,0 @@ -cloud.aws.sns.enabled=false diff --git a/spring-cloud-aws-sqs-testing/src/test/java/de/rieckpil/OrderListenerTest.java b/spring-cloud-aws-sqs-testing/src/test/java/de/rieckpil/OrderListenerTest.java index dd5b4a83..06b5d018 100644 --- a/spring-cloud-aws-sqs-testing/src/test/java/de/rieckpil/OrderListenerTest.java +++ b/spring-cloud-aws-sqs-testing/src/test/java/de/rieckpil/OrderListenerTest.java @@ -1,14 +1,19 @@ package de.rieckpil; -import java.time.Duration; -import java.util.Map; +import static org.awaitility.Awaitility.await; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.verify; +import static org.testcontainers.containers.localstack.LocalStackContainer.Service; +import static org.testcontainers.containers.localstack.LocalStackContainer.Service.SQS; -import io.awspring.cloud.messaging.core.QueueMessagingTemplate; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import io.awspring.cloud.sqs.operations.SqsTemplate; import io.awspring.cloud.test.sqs.SqsTest; +import java.time.Duration; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.messaging.support.GenericMessage; import org.springframework.test.context.DynamicPropertyRegistry; import org.springframework.test.context.DynamicPropertySource; import org.testcontainers.containers.BindMode; @@ -18,56 +23,41 @@ import org.testcontainers.junit.jupiter.Testcontainers; import org.testcontainers.utility.DockerImageName; -import static org.assertj.core.api.Assertions.assertThat; -import static org.awaitility.Awaitility.await; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.verify; -import static org.testcontainers.containers.localstack.LocalStackContainer.*; -import static org.testcontainers.containers.localstack.LocalStackContainer.Service.SQS; - @Testcontainers @SqsTest(OrderListener.class) class OrderListenerTest { @Container - static LocalStackContainer localStack = new LocalStackContainer(DockerImageName.parse("localstack/localstack:0.14.3")) - .withClasspathResourceMapping("/localstack", "/docker-entrypoint-initaws.d", BindMode.READ_ONLY) - .withServices(Service.SQS) - .waitingFor(Wait.forLogMessage(".*Initialized\\.\n", 1)); + static LocalStackContainer localStack = + new LocalStackContainer(DockerImageName.parse("localstack/localstack:0.14.3")) + .withClasspathResourceMapping( + "/localstack", "/docker-entrypoint-initaws.d", BindMode.READ_ONLY) + .withServices(Service.SQS) + .waitingFor(Wait.forLogMessage(".*Initialized\\.\n", 1)); @DynamicPropertySource static void properties(DynamicPropertyRegistry registry) { - registry.add("cloud.aws.sqs.endpoint", () -> localStack.getEndpointOverride(SQS).toString()); - registry.add("cloud.aws.credentials.access-key", () -> "foo"); - registry.add("cloud.aws.credentials.secret-key", () -> "bar"); - registry.add("cloud.aws.region.static", () -> localStack.getRegion()); + registry.add( + "spring.cloud.aws.sqs.endpoint", () -> localStack.getEndpointOverride(SQS).toString()); + registry.add("spring.cloud.aws.credentials.access-key", () -> "foo"); + registry.add("spring.cloud.aws.credentials.secret-key", () -> "bar"); + registry.add("spring.cloud.aws.region.static", () -> localStack.getRegion()); registry.add("order-queue-name", () -> "test-order-queue"); } - @Autowired - private QueueMessagingTemplate queueMessagingTemplate; + @Autowired private SqsTemplate sqsTemplate; - @MockBean - private PurchaseOrderRepository purchaseOrderRepository; + @MockBean private PurchaseOrderRepository purchaseOrderRepository; @Test - void shouldStoreIncomingPurchaseOrderInDatabase() { - - Map messageHeaders = Map.of("contentType", "application/json"); - - String payload = """ - { - "customer_name": "duke", - "order_amount": 42 - } - """; + void shouldStoreIncomingPurchaseOrderInDatabase() throws JsonProcessingException { - queueMessagingTemplate - .send("test-order-queue", new GenericMessage<>(payload, messageHeaders)); + sqsTemplate.send( + "test-order-queue", + new ObjectMapper().writeValueAsString(new PurchaseOrderPayload("duke", 42L))); await() - .atMost(Duration.ofSeconds(3)) - .untilAsserted(() -> verify(purchaseOrderRepository).save(any(PurchaseOrder.class))); + .atMost(Duration.ofSeconds(3)) + .untilAsserted(() -> verify(purchaseOrderRepository).save(any(PurchaseOrder.class))); } } diff --git a/spring-data-mongo-test-testcontainers/pom.xml b/spring-data-mongo-test-testcontainers/pom.xml index baa30fdc..d37f2088 100644 --- a/spring-data-mongo-test-testcontainers/pom.xml +++ b/spring-data-mongo-test-testcontainers/pom.xml @@ -2,23 +2,19 @@ 4.0.0 + - org.springframework.boot - spring-boot-starter-parent - 2.4.0 - + de.rieckpil.blog + blog-parent + 0.0.1-SNAPSHOT + ../pom.xml - de.rieckpil.blog + spring-data-mongo-test-testcontainers 0.0.1-SNAPSHOT spring-data-mongo-test-testcontainers - - 11 - 1.16.0 - - org.springframework.boot @@ -46,18 +42,6 @@ - - - - org.testcontainers - testcontainers-bom - ${testcontainers.version} - pom - import - - - - diff --git a/spring-data-mongo-test-testcontainers/src/main/java/de/rieckpil/blog/Application.java b/spring-data-mongo-test-testcontainers/src/main/java/de/rieckpil/blog/Application.java index bd5e4c56..6511f3c1 100644 --- a/spring-data-mongo-test-testcontainers/src/main/java/de/rieckpil/blog/Application.java +++ b/spring-data-mongo-test-testcontainers/src/main/java/de/rieckpil/blog/Application.java @@ -9,5 +9,4 @@ public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } - } diff --git a/spring-data-mongo-test-testcontainers/src/main/java/de/rieckpil/blog/Customer.java b/spring-data-mongo-test-testcontainers/src/main/java/de/rieckpil/blog/Customer.java index 69f1a2c4..4871fe56 100644 --- a/spring-data-mongo-test-testcontainers/src/main/java/de/rieckpil/blog/Customer.java +++ b/spring-data-mongo-test-testcontainers/src/main/java/de/rieckpil/blog/Customer.java @@ -6,16 +6,13 @@ @Document public class Customer { - @Id - private String id; + @Id private String id; private String email; private Integer rating; - public Customer() { - - } + public Customer() {} public Customer(String email, Integer rating) { this.email = email; diff --git a/spring-data-mongo-test-testcontainers/src/main/java/de/rieckpil/blog/CustomerRepository.java b/spring-data-mongo-test-testcontainers/src/main/java/de/rieckpil/blog/CustomerRepository.java index ebb9e65e..59f6f784 100644 --- a/spring-data-mongo-test-testcontainers/src/main/java/de/rieckpil/blog/CustomerRepository.java +++ b/spring-data-mongo-test-testcontainers/src/main/java/de/rieckpil/blog/CustomerRepository.java @@ -1,10 +1,9 @@ package de.rieckpil.blog; +import java.util.List; import org.springframework.data.mongodb.repository.MongoRepository; import org.springframework.data.mongodb.repository.Query; -import java.util.List; - public interface CustomerRepository extends MongoRepository { @Query(sort = "{ rating : 1 }") diff --git a/spring-data-mongo-test-testcontainers/src/main/java/de/rieckpil/blog/CustomerService.java b/spring-data-mongo-test-testcontainers/src/main/java/de/rieckpil/blog/CustomerService.java index 6582d42d..e78b237f 100644 --- a/spring-data-mongo-test-testcontainers/src/main/java/de/rieckpil/blog/CustomerService.java +++ b/spring-data-mongo-test-testcontainers/src/main/java/de/rieckpil/blog/CustomerService.java @@ -1,12 +1,11 @@ package de.rieckpil.blog; +import java.util.List; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.Query; import org.springframework.stereotype.Service; -import java.util.List; - @Service public class CustomerService { diff --git a/spring-data-mongo-test-testcontainers/src/test/java/de/rieckpil/blog/CustomerRepositoryTest.java b/spring-data-mongo-test-testcontainers/src/test/java/de/rieckpil/blog/CustomerRepositoryTest.java index 4d7f6ad9..f689e042 100644 --- a/spring-data-mongo-test-testcontainers/src/test/java/de/rieckpil/blog/CustomerRepositoryTest.java +++ b/spring-data-mongo-test-testcontainers/src/test/java/de/rieckpil/blog/CustomerRepositoryTest.java @@ -1,9 +1,11 @@ package de.rieckpil.blog; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.List; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration; import org.springframework.boot.test.autoconfigure.data.mongo.DataMongoTest; import org.springframework.test.context.DynamicPropertyRegistry; import org.springframework.test.context.DynamicPropertySource; @@ -11,24 +13,18 @@ import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.util.List; - -import static org.junit.jupiter.api.Assertions.assertEquals; - @Testcontainers -@DataMongoTest(excludeAutoConfiguration = EmbeddedMongoAutoConfiguration.class) +@DataMongoTest class CustomerRepositoryTest { - @Container - static MongoDBContainer mongoDBContainer = new MongoDBContainer("mongo:4.4.2"); + @Container static MongoDBContainer mongoDBContainer = new MongoDBContainer("mongo:4.4.2"); @DynamicPropertySource static void setProperties(DynamicPropertyRegistry registry) { registry.add("spring.data.mongodb.uri", mongoDBContainer::getReplicaSetUrl); } - @Autowired - private CustomerRepository customerRepository; + @Autowired private CustomerRepository customerRepository; @AfterEach void cleanUp() { @@ -59,4 +55,3 @@ void shouldReturnOrderedListOfCustomer() { assertEquals("mike@spring.io", customers.get(2).getEmail()); } } - diff --git a/spring-data-mongo-test-testcontainers/src/test/java/de/rieckpil/blog/CustomerServiceTest.java b/spring-data-mongo-test-testcontainers/src/test/java/de/rieckpil/blog/CustomerServiceTest.java index 3009b32b..7307c8d7 100644 --- a/spring-data-mongo-test-testcontainers/src/test/java/de/rieckpil/blog/CustomerServiceTest.java +++ b/spring-data-mongo-test-testcontainers/src/test/java/de/rieckpil/blog/CustomerServiceTest.java @@ -1,9 +1,11 @@ package de.rieckpil.blog; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.List; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration; import org.springframework.boot.test.autoconfigure.data.mongo.DataMongoTest; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.test.context.DynamicPropertyRegistry; @@ -12,24 +14,18 @@ import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import java.util.List; - -import static org.junit.jupiter.api.Assertions.assertEquals; - @Testcontainers -@DataMongoTest(excludeAutoConfiguration = EmbeddedMongoAutoConfiguration.class) +@DataMongoTest class CustomerServiceTest { - @Container - static MongoDBContainer mongoDBContainer = new MongoDBContainer("mongo:4.4.2"); + @Container static MongoDBContainer mongoDBContainer = new MongoDBContainer("mongo:4.4.2"); @DynamicPropertySource static void setProperties(DynamicPropertyRegistry registry) { registry.add("spring.data.mongodb.uri", mongoDBContainer::getReplicaSetUrl); } - @Autowired - private MongoTemplate mongoTemplate; + @Autowired private MongoTemplate mongoTemplate; private CustomerService cut; diff --git a/spring-mockmvc-with-webtestclient/.java-version b/spring-mockmvc-with-webtestclient/.java-version new file mode 100644 index 00000000..5f39e914 --- /dev/null +++ b/spring-mockmvc-with-webtestclient/.java-version @@ -0,0 +1 @@ +21.0 diff --git a/spring-mockmvc-with-webtestclient/src/main/java/de/rieckpil/blog/Application.java b/spring-mockmvc-with-webtestclient/src/main/java/de/rieckpil/blog/Application.java index bd5e4c56..6511f3c1 100644 --- a/spring-mockmvc-with-webtestclient/src/main/java/de/rieckpil/blog/Application.java +++ b/spring-mockmvc-with-webtestclient/src/main/java/de/rieckpil/blog/Application.java @@ -9,5 +9,4 @@ public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } - } diff --git a/spring-mockmvc-with-webtestclient/src/main/java/de/rieckpil/blog/DashboardController.java b/spring-mockmvc-with-webtestclient/src/main/java/de/rieckpil/blog/DashboardController.java index 934aa897..51e5deaf 100644 --- a/spring-mockmvc-with-webtestclient/src/main/java/de/rieckpil/blog/DashboardController.java +++ b/spring-mockmvc-with-webtestclient/src/main/java/de/rieckpil/blog/DashboardController.java @@ -1,12 +1,11 @@ package de.rieckpil.blog; +import java.util.Arrays; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; -import java.util.Arrays; - @Controller @RequestMapping("/dashboard") public class DashboardController { diff --git a/spring-mockmvc-with-webtestclient/src/main/java/de/rieckpil/blog/User.java b/spring-mockmvc-with-webtestclient/src/main/java/de/rieckpil/blog/User.java index 8f25fb63..3cc9e3c4 100644 --- a/spring-mockmvc-with-webtestclient/src/main/java/de/rieckpil/blog/User.java +++ b/spring-mockmvc-with-webtestclient/src/main/java/de/rieckpil/blog/User.java @@ -8,15 +8,12 @@ class User { - @NotNull - private Long id; + @NotNull private Long id; - @NotEmpty - private String name; + @NotEmpty private String name; private Set tags; - public User() { - } + public User() {} public User(Long id, String name) { this.name = name; @@ -59,9 +56,9 @@ public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; User user = (User) o; - return Objects.equals(id, user.id) && - Objects.equals(name, user.name) && - Objects.equals(tags, user.tags); + return Objects.equals(id, user.id) + && Objects.equals(name, user.name) + && Objects.equals(tags, user.tags); } @Override diff --git a/spring-mockmvc-with-webtestclient/src/main/java/de/rieckpil/blog/UserController.java b/spring-mockmvc-with-webtestclient/src/main/java/de/rieckpil/blog/UserController.java index 5151ea3e..682e262f 100644 --- a/spring-mockmvc-with-webtestclient/src/main/java/de/rieckpil/blog/UserController.java +++ b/spring-mockmvc-with-webtestclient/src/main/java/de/rieckpil/blog/UserController.java @@ -1,15 +1,14 @@ package de.rieckpil.blog; +import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; + +import java.util.List; import org.springframework.http.ResponseEntity; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import org.springframework.web.util.UriComponents; import org.springframework.web.util.UriComponentsBuilder; -import java.util.List; - -import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; - @RestController @RequestMapping(value = "/api/users", produces = APPLICATION_JSON_VALUE) public class UserController { @@ -28,18 +27,24 @@ public List getAllUsers() { @GetMapping("/{id}") public User getUserById(@PathVariable("id") Long id) { return userService - .getUserById(id) - .orElseThrow(() -> new UserNotFoundException(String.format("User with id [%s] not found", id))); + .getUserById(id) + .orElseThrow( + () -> new UserNotFoundException(String.format("User with id [%s] not found", id))); } @PostMapping(consumes = APPLICATION_JSON_VALUE) - public ResponseEntity createNewUser(@RequestBody @Validated User user, UriComponentsBuilder uriComponentsBuilder) { - User addedUser = this.userService.addNewUser(user) - .orElseThrow(() -> new UserAlreadyExistsException( - String.format("User with id [%s] is already present", user.getId()))); + public ResponseEntity createNewUser( + @RequestBody @Validated User user, UriComponentsBuilder uriComponentsBuilder) { + User addedUser = + this.userService + .addNewUser(user) + .orElseThrow( + () -> + new UserAlreadyExistsException( + String.format("User with id [%s] is already present", user.getId()))); UriComponents uriComponents = - uriComponentsBuilder.path("/api/users/{id}").buildAndExpand(addedUser.getId()); + uriComponentsBuilder.path("/api/users/{id}").buildAndExpand(addedUser.getId()); return ResponseEntity.created(uriComponents.toUri()).build(); } @@ -49,4 +54,3 @@ public void deleteUser(@PathVariable("id") Long id) { this.userService.deleteUserById(id); } } - diff --git a/spring-mockmvc-with-webtestclient/src/main/java/de/rieckpil/blog/UserService.java b/spring-mockmvc-with-webtestclient/src/main/java/de/rieckpil/blog/UserService.java index 3f1519c2..cbb2ffdd 100644 --- a/spring-mockmvc-with-webtestclient/src/main/java/de/rieckpil/blog/UserService.java +++ b/spring-mockmvc-with-webtestclient/src/main/java/de/rieckpil/blog/UserService.java @@ -1,12 +1,11 @@ package de.rieckpil.blog; import jakarta.annotation.PostConstruct; -import org.springframework.stereotype.Service; - import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.Set; +import org.springframework.stereotype.Service; @Service public class UserService { @@ -26,9 +25,7 @@ public List getAllUsers() { } public Optional getUserById(Long id) { - return this.userList.stream() - .filter(user -> user.getId() == id) - .findFirst(); + return this.userList.stream().filter(user -> user.getId() == id).findFirst(); } public Optional addNewUser(User user) { diff --git a/spring-mockmvc-with-webtestclient/src/main/java/de/rieckpil/blog/WebSecurityConfig.java b/spring-mockmvc-with-webtestclient/src/main/java/de/rieckpil/blog/WebSecurityConfig.java index 56d66b5f..31b70db7 100644 --- a/spring-mockmvc-with-webtestclient/src/main/java/de/rieckpil/blog/WebSecurityConfig.java +++ b/spring-mockmvc-with-webtestclient/src/main/java/de/rieckpil/blog/WebSecurityConfig.java @@ -1,25 +1,28 @@ package de.rieckpil.blog; +import static org.springframework.security.config.Customizer.withDefaults; + import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpMethod; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.web.SecurityFilterChain; -import static org.springframework.security.config.Customizer.withDefaults; - @Configuration -public class WebSecurityConfig { +public class WebSecurityConfig { @Bean public SecurityFilterChain configure(HttpSecurity http) throws Exception { - http - .authorizeHttpRequests(authorize -> authorize - .requestMatchers(HttpMethod.GET, "/dashboard").permitAll() - .requestMatchers("/api/users/**").authenticated() - .requestMatchers("/**").authenticated() - ) - .httpBasic(withDefaults()); + http.authorizeHttpRequests( + authorize -> + authorize + .requestMatchers(HttpMethod.GET, "/dashboard") + .permitAll() + .requestMatchers("/api/users/**") + .authenticated() + .requestMatchers("/**") + .authenticated()) + .httpBasic(withDefaults()); return http.build(); } diff --git a/spring-mockmvc-with-webtestclient/src/test/java/de/rieckpil/blog/ApplicationTests.java b/spring-mockmvc-with-webtestclient/src/test/java/de/rieckpil/blog/ApplicationTests.java index 6158e9b9..da34f8f8 100644 --- a/spring-mockmvc-with-webtestclient/src/test/java/de/rieckpil/blog/ApplicationTests.java +++ b/spring-mockmvc-with-webtestclient/src/test/java/de/rieckpil/blog/ApplicationTests.java @@ -1,24 +1,19 @@ package de.rieckpil.blog; +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment; + import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.web.reactive.server.WebTestClient; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment; - @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) class ApplicationTests { - @Autowired - private WebTestClient webTestClient; + @Autowired private WebTestClient webTestClient; @Test void contextLoads() { - this.webTestClient - .get() - .uri("/api/users") - .exchange() - .expectStatus().is4xxClientError(); + this.webTestClient.get().uri("/api/users").exchange().expectStatus().is4xxClientError(); } } diff --git a/spring-mockmvc-with-webtestclient/src/test/java/de/rieckpil/blog/DashboardControllerTest.java b/spring-mockmvc-with-webtestclient/src/test/java/de/rieckpil/blog/DashboardControllerTest.java index 72e49fe2..58f5f65c 100644 --- a/spring-mockmvc-with-webtestclient/src/test/java/de/rieckpil/blog/DashboardControllerTest.java +++ b/spring-mockmvc-with-webtestclient/src/test/java/de/rieckpil/blog/DashboardControllerTest.java @@ -1,5 +1,8 @@ package de.rieckpil.blog; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.model; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view; + import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -10,41 +13,37 @@ import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.client.MockMvcWebTestClient; -import static org.springframework.security.test.web.reactive.server.SecurityMockServerConfigurers.mockUser; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.model; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view; - @Import(WebSecurityConfig.class) @WebMvcTest(DashboardController.class) class DashboardControllerTest { - @Autowired - private MockMvc mockMvc; + @Autowired private MockMvc mockMvc; private WebTestClient webTestClient; @BeforeEach void setup() { - this.webTestClient = MockMvcWebTestClient - .bindTo(mockMvc) - .build(); + this.webTestClient = MockMvcWebTestClient.bindTo(mockMvc).build(); } @Test void shouldReturnDashboardViewWithDefaultModel() throws Exception { - EntityExchangeResult result = this.webTestClient - .get() - .uri("/dashboard") - .exchange() - .expectStatus().is2xxSuccessful() - .expectBody().returnResult(); + EntityExchangeResult result = + this.webTestClient + .get() + .uri("/dashboard") + .exchange() + .expectStatus() + .is2xxSuccessful() + .expectBody() + .returnResult(); MockMvcWebTestClient.resultActionsFor(result) - .andExpect(model().size(2)) - .andExpect(model().attributeExists("message")) - .andExpect(model().attributeExists("orderIds")) - .andExpect(model().attribute("message", "Hello World!")) - .andExpect(view().name("dashboard")); + .andExpect(model().size(2)) + .andExpect(model().attributeExists("message")) + .andExpect(model().attributeExists("orderIds")) + .andExpect(model().attribute("message", "Hello World!")) + .andExpect(view().name("dashboard")); } } diff --git a/spring-mockmvc-with-webtestclient/src/test/java/de/rieckpil/blog/UserControllerMockMvcTest.java b/spring-mockmvc-with-webtestclient/src/test/java/de/rieckpil/blog/UserControllerMockMvcTest.java index e7b86cdc..f419f77c 100644 --- a/spring-mockmvc-with-webtestclient/src/test/java/de/rieckpil/blog/UserControllerMockMvcTest.java +++ b/spring-mockmvc-with-webtestclient/src/test/java/de/rieckpil/blog/UserControllerMockMvcTest.java @@ -1,5 +1,10 @@ package de.rieckpil.blog; +import static org.mockito.Mockito.when; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import java.util.List; import org.hamcrest.Matchers; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -10,27 +15,19 @@ import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; -import java.util.List; - -import static org.mockito.Mockito.when; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - @Import(WebSecurityConfig.class) @WebMvcTest(UserController.class) class UserControllerMockMvcTest { - @Autowired - private MockMvc mockMvc; + @Autowired private MockMvc mockMvc; - @MockBean - private UserService userService; + @MockBean private UserService userService; @Test void shouldForbidAccessToUnauthenticatedRequests() throws Exception { this.mockMvc - .perform(MockMvcRequestBuilders.get("/api/users")) - .andExpect(status().is4xxClientError()); + .perform(MockMvcRequestBuilders.get("/api/users")) + .andExpect(status().is4xxClientError()); } @Test @@ -38,11 +35,11 @@ void shouldForbidAccessToUnauthenticatedRequests() throws Exception { void shouldReturnListOfUsersForAuthenticatedRequests() throws Exception { when(userService.getAllUsers()) - .thenReturn(List.of(new User(42L, "duke"), new User(24L, "mike"))); + .thenReturn(List.of(new User(42L, "duke"), new User(24L, "mike"))); this.mockMvc - .perform(MockMvcRequestBuilders.get("/api/users")) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.size()", Matchers.is(2))); + .perform(MockMvcRequestBuilders.get("/api/users")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.size()", Matchers.is(2))); } } diff --git a/spring-mockmvc-with-webtestclient/src/test/java/de/rieckpil/blog/UserControllerTest.java b/spring-mockmvc-with-webtestclient/src/test/java/de/rieckpil/blog/UserControllerTest.java index 8850dbea..d9980fd9 100644 --- a/spring-mockmvc-with-webtestclient/src/test/java/de/rieckpil/blog/UserControllerTest.java +++ b/spring-mockmvc-with-webtestclient/src/test/java/de/rieckpil/blog/UserControllerTest.java @@ -1,5 +1,8 @@ package de.rieckpil.blog; +import static org.mockito.Mockito.when; + +import java.util.List; import org.hamcrest.Matchers; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -12,42 +15,38 @@ import org.springframework.test.web.servlet.client.MockMvcWebTestClient; import org.springframework.web.reactive.function.client.ExchangeFilterFunction; -import java.util.List; - -import static org.mockito.Mockito.when; - @WebMvcTest(UserController.class) class UserControllerTest { - @Autowired - private MockMvc mockMvc; + @Autowired private MockMvc mockMvc; - @MockBean - private UserService userService; + @MockBean private UserService userService; private WebTestClient webTestClient; @BeforeEach public void setup() { - this.webTestClient = MockMvcWebTestClient - .bindTo(mockMvc) - .defaultHeader("X-Duke", "42") - .filter(logRequest()) - .build(); + this.webTestClient = + MockMvcWebTestClient.bindTo(mockMvc) + .defaultHeader("X-Duke", "42") + .filter(logRequest()) + .build(); } @Test @WithMockUser(username = "duke") void shouldReturnListOfUsersForAuthenticatedRequests() { when(userService.getAllUsers()) - .thenReturn(List.of(new User(42L, "duke"), new User(24L, "mike"))); + .thenReturn(List.of(new User(42L, "duke"), new User(24L, "mike"))); this.webTestClient - .get() - .uri("/api/users") - .exchange() - .expectStatus().is2xxSuccessful() - .expectBody().jsonPath("$.size()", Matchers.is(2)); + .get() + .uri("/api/users") + .exchange() + .expectStatus() + .is2xxSuccessful() + .expectBody() + .jsonPath("$.size()", Matchers.is(2)); } private ExchangeFilterFunction logRequest() { diff --git a/spring-security-aws-cognito-thymeleaf/pom.xml b/spring-security-aws-cognito-thymeleaf/pom.xml index df49716c..807c2b32 100644 --- a/spring-security-aws-cognito-thymeleaf/pom.xml +++ b/spring-security-aws-cognito-thymeleaf/pom.xml @@ -4,22 +4,17 @@ 4.0.0 - org.springframework.boot - spring-boot-starter-parent - 2.3.0.RELEASE - + de.rieckpil.blog + blog-parent + 0.0.1-SNAPSHOT + ../pom.xml - de.rieckpil.blog spring-security-aws-cognito-thymeleaf 0.0.1-SNAPSHOT spring-security-aws-cognito-thymeleaf Demo project using AWS Cognito with Spring Security - - 11 - - org.springframework.boot @@ -40,19 +35,13 @@ org.thymeleaf.extras - thymeleaf-extras-springsecurity5 + thymeleaf-extras-springsecurity6 org.springframework.boot spring-boot-starter-test test - - - org.junit.vintage - junit-vintage-engine - - org.springframework.security diff --git a/spring-security-aws-cognito-thymeleaf/src/main/java/de/rieckpil/blog/Application.java b/spring-security-aws-cognito-thymeleaf/src/main/java/de/rieckpil/blog/Application.java index bd5e4c56..6511f3c1 100644 --- a/spring-security-aws-cognito-thymeleaf/src/main/java/de/rieckpil/blog/Application.java +++ b/spring-security-aws-cognito-thymeleaf/src/main/java/de/rieckpil/blog/Application.java @@ -9,5 +9,4 @@ public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } - } diff --git a/spring-security-aws-cognito-thymeleaf/src/main/java/de/rieckpil/blog/CognitoOidcLogoutSuccessHandler.java b/spring-security-aws-cognito-thymeleaf/src/main/java/de/rieckpil/blog/CognitoOidcLogoutSuccessHandler.java index 811d6f15..3d86eb07 100644 --- a/spring-security-aws-cognito-thymeleaf/src/main/java/de/rieckpil/blog/CognitoOidcLogoutSuccessHandler.java +++ b/spring-security-aws-cognito-thymeleaf/src/main/java/de/rieckpil/blog/CognitoOidcLogoutSuccessHandler.java @@ -1,16 +1,15 @@ package de.rieckpil.blog; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import java.net.URI; +import java.nio.charset.StandardCharsets; import org.springframework.security.core.Authentication; import org.springframework.security.web.authentication.logout.SimpleUrlLogoutSuccessHandler; import org.springframework.security.web.util.UrlUtils; import org.springframework.web.util.UriComponents; import org.springframework.web.util.UriComponentsBuilder; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.net.URI; -import java.nio.charset.StandardCharsets; - public class CognitoOidcLogoutSuccessHandler extends SimpleUrlLogoutSuccessHandler { private final String logoutUrl; @@ -22,22 +21,21 @@ public CognitoOidcLogoutSuccessHandler(String logoutUrl, String clientId) { } @Override - protected String determineTargetUrl(HttpServletRequest request, HttpServletResponse response, - Authentication authentication) { - - UriComponents baseUrl = UriComponentsBuilder - .fromHttpUrl(UrlUtils.buildFullRequestUrl(request)) - .replacePath(request.getContextPath()) - .replaceQuery(null) - .fragment(null) - .build(); - - return UriComponentsBuilder - .fromUri(URI.create(logoutUrl)) - .queryParam("client_id", clientId) - .queryParam("logout_uri", baseUrl) - .encode(StandardCharsets.UTF_8) - .build() - .toUriString(); + protected String determineTargetUrl( + HttpServletRequest request, HttpServletResponse response, Authentication authentication) { + + UriComponents baseUrl = + UriComponentsBuilder.fromHttpUrl(UrlUtils.buildFullRequestUrl(request)) + .replacePath(request.getContextPath()) + .replaceQuery(null) + .fragment(null) + .build(); + + return UriComponentsBuilder.fromUri(URI.create(logoutUrl)) + .queryParam("client_id", clientId) + .queryParam("logout_uri", baseUrl) + .encode(StandardCharsets.UTF_8) + .build() + .toUriString(); } } diff --git a/spring-security-aws-cognito-thymeleaf/src/main/java/de/rieckpil/blog/IndexController.java b/spring-security-aws-cognito-thymeleaf/src/main/java/de/rieckpil/blog/IndexController.java index efed2d96..b8f2ef29 100644 --- a/spring-security-aws-cognito-thymeleaf/src/main/java/de/rieckpil/blog/IndexController.java +++ b/spring-security-aws-cognito-thymeleaf/src/main/java/de/rieckpil/blog/IndexController.java @@ -11,7 +11,8 @@ public class IndexController { @GetMapping public String getIndexPage(Model model, Authentication authentication) { if (authentication != null && authentication.isAuthenticated()) { - if (authentication.getAuthorities().stream().anyMatch(a -> a.getAuthority().equals("ROLE_ADMIN"))) { + if (authentication.getAuthorities().stream() + .anyMatch(a -> a.getAuthority().equals("ROLE_ADMIN"))) { model.addAttribute("secretMessage", "Admin message is s3crEt"); } else { model.addAttribute("secretMessage", "Lorem ipsum dolor sit amet"); diff --git a/spring-security-aws-cognito-thymeleaf/src/main/java/de/rieckpil/blog/WebSecurityConfig.java b/spring-security-aws-cognito-thymeleaf/src/main/java/de/rieckpil/blog/WebSecurityConfig.java index 566aeeaf..8dd18e55 100644 --- a/spring-security-aws-cognito-thymeleaf/src/main/java/de/rieckpil/blog/WebSecurityConfig.java +++ b/spring-security-aws-cognito-thymeleaf/src/main/java/de/rieckpil/blog/WebSecurityConfig.java @@ -1,33 +1,36 @@ package de.rieckpil.blog; import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.Customizer; import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.web.SecurityFilterChain; @Configuration -public class WebSecurityConfig extends WebSecurityConfigurerAdapter { +public class WebSecurityConfig { private final String clientId; private final String logoutUrl; - public WebSecurityConfig(@Value("${spring.security.oauth2.client.registration.cognito.clientId}") String clientId, - @Value("${cognito.logoutUrl}") String logoutUrl) { + public WebSecurityConfig( + @Value("${spring.security.oauth2.client.registration.cognito.clientId}") String clientId, + @Value("${cognito.logoutUrl}") String logoutUrl) { this.clientId = clientId; this.logoutUrl = logoutUrl; } - @Override - protected void configure(HttpSecurity http) throws Exception { - http - .csrf() - .and() - .authorizeRequests(authorize -> - authorize.mvcMatchers("/").permitAll() - .anyRequest().authenticated()) - .oauth2Login() - .and() - .logout() - .logoutSuccessHandler(new CognitoOidcLogoutSuccessHandler(logoutUrl, clientId)); + @Bean + public SecurityFilterChain configure(HttpSecurity http) throws Exception { + http.csrf(Customizer.withDefaults()) + .authorizeHttpRequests( + authorize -> authorize.requestMatchers("/").permitAll().anyRequest().authenticated()) + .oauth2Login(Customizer.withDefaults()) + .logout( + logout -> + logout.logoutSuccessHandler( + new CognitoOidcLogoutSuccessHandler(logoutUrl, clientId))); + + return http.build(); } } diff --git a/spring-security-aws-cognito-thymeleaf/src/test/java/de/rieckpil/blog/IndexControllerTest.java b/spring-security-aws-cognito-thymeleaf/src/test/java/de/rieckpil/blog/IndexControllerTest.java index de5cea06..dbc36719 100644 --- a/spring-security-aws-cognito-thymeleaf/src/test/java/de/rieckpil/blog/IndexControllerTest.java +++ b/spring-security-aws-cognito-thymeleaf/src/test/java/de/rieckpil/blog/IndexControllerTest.java @@ -1,5 +1,10 @@ package de.rieckpil.blog; +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.*; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.model; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + import org.hamcrest.Matchers; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; @@ -8,45 +13,37 @@ import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.test.web.servlet.MockMvc; -import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.*; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.model; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - @Disabled @WebMvcTest class IndexControllerTest { - @Autowired - private MockMvc mockMvc; + @Autowired private MockMvc mockMvc; @Test void anonymousUsersShouldNotGetSecretMessage() throws Exception { this.mockMvc - .perform(get("/") - .with(anonymous())) - .andExpect(status().isOk()) - .andExpect(model().attributeDoesNotExist("secretMessage")) - .andExpect(model().attribute("message", "AWS Cognito with Spring Security")); + .perform(get("/").with(anonymous())) + .andExpect(status().isOk()) + .andExpect(model().attributeDoesNotExist("secretMessage")) + .andExpect(model().attribute("message", "AWS Cognito with Spring Security")); } @Test void authenticatedUsersShouldGetSecretMessage() throws Exception { this.mockMvc - .perform(get("/") - .with(oidcLogin())) - .andExpect(status().isOk()) - .andExpect(model().attributeExists("secretMessage", "message")) - .andExpect(model().attribute("secretMessage", Matchers.stringContainsInOrder("Lorem ipsum"))); + .perform(get("/").with(oidcLogin())) + .andExpect(status().isOk()) + .andExpect(model().attributeExists("secretMessage", "message")) + .andExpect( + model().attribute("secretMessage", Matchers.stringContainsInOrder("Lorem ipsum"))); } @Test void authenticatedAdminUsersShouldGetDetailedSecretMessage() throws Exception { this.mockMvc - .perform(get("/") - .with(oidcLogin().authorities(new SimpleGrantedAuthority("ROLE_ADMIN")))) - .andExpect(status().isOk()) - .andExpect(model().attributeExists("secretMessage", "message")) - .andExpect(model().attribute("secretMessage", "Admin message is s3crEt")); + .perform(get("/").with(oidcLogin().authorities(new SimpleGrantedAuthority("ROLE_ADMIN")))) + .andExpect(status().isOk()) + .andExpect(model().attributeExists("secretMessage", "message")) + .andExpect(model().attribute("secretMessage", "Admin message is s3crEt")); } } diff --git a/spring-test-context-caching-introduction/pom.xml b/spring-test-context-caching-introduction/pom.xml index 1ae4f638..04a1ba12 100644 --- a/spring-test-context-caching-introduction/pom.xml +++ b/spring-test-context-caching-introduction/pom.xml @@ -2,22 +2,19 @@ 4.0.0 + - org.springframework.boot - spring-boot-starter-parent - 2.3.0.RELEASE - + de.rieckpil.blog + blog-parent + 0.0.1-SNAPSHOT + ../pom.xml - de.rieckpil.blog + spring-test-context-caching-introduction 0.0.1-SNAPSHOT spring-test-context-caching-introduction Demo project for Spring Boot - - 11 - - org.springframework.boot diff --git a/spring-test-context-caching-introduction/src/main/java/de/rieckpil/blog/Application.java b/spring-test-context-caching-introduction/src/main/java/de/rieckpil/blog/Application.java index bd5e4c56..6511f3c1 100644 --- a/spring-test-context-caching-introduction/src/main/java/de/rieckpil/blog/Application.java +++ b/spring-test-context-caching-introduction/src/main/java/de/rieckpil/blog/Application.java @@ -9,5 +9,4 @@ public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } - } diff --git a/spring-test-context-caching-introduction/src/main/java/de/rieckpil/blog/CustomInitializer.java b/spring-test-context-caching-introduction/src/main/java/de/rieckpil/blog/CustomInitializer.java index 70b9aaea..d14c0564 100644 --- a/spring-test-context-caching-introduction/src/main/java/de/rieckpil/blog/CustomInitializer.java +++ b/spring-test-context-caching-introduction/src/main/java/de/rieckpil/blog/CustomInitializer.java @@ -3,7 +3,8 @@ import org.springframework.context.ApplicationContextInitializer; import org.springframework.context.ConfigurableApplicationContext; -public class CustomInitializer implements ApplicationContextInitializer { +public class CustomInitializer + implements ApplicationContextInitializer { @Override public void initialize(ConfigurableApplicationContext configurableApplicationContext) { System.out.println("Init stuff"); diff --git a/spring-test-context-caching-introduction/src/test/java/de/rieckpil/blog/AbstractIntegrationTest.java b/spring-test-context-caching-introduction/src/test/java/de/rieckpil/blog/AbstractIntegrationTest.java index ffcfac19..d0e1d927 100644 --- a/spring-test-context-caching-introduction/src/test/java/de/rieckpil/blog/AbstractIntegrationTest.java +++ b/spring-test-context-caching-introduction/src/test/java/de/rieckpil/blog/AbstractIntegrationTest.java @@ -1,12 +1,12 @@ package de.rieckpil.blog; +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; + import org.junit.jupiter.api.BeforeAll; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.ContextConfiguration; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - @AutoConfigureMockMvc @ContextConfiguration(initializers = CustomInitializer.class) @SpringBootTest(webEnvironment = RANDOM_PORT) @@ -17,4 +17,3 @@ public static void commonSetup() { // e.g. provide WireMock stubs } } - diff --git a/spring-test-context-caching-introduction/src/test/java/de/rieckpil/blog/ApplicationTests.java b/spring-test-context-caching-introduction/src/test/java/de/rieckpil/blog/ApplicationTests.java index 874de1b2..4f1f1cf4 100644 --- a/spring-test-context-caching-introduction/src/test/java/de/rieckpil/blog/ApplicationTests.java +++ b/spring-test-context-caching-introduction/src/test/java/de/rieckpil/blog/ApplicationTests.java @@ -7,7 +7,5 @@ class ApplicationTests { @Test - void contextLoads() { - } - + void contextLoads() {} } diff --git a/spring-test-context-caching-introduction/src/test/java/de/rieckpil/blog/SecondApplicationTest.java b/spring-test-context-caching-introduction/src/test/java/de/rieckpil/blog/SecondApplicationTest.java index 8361f48c..8482aa82 100644 --- a/spring-test-context-caching-introduction/src/test/java/de/rieckpil/blog/SecondApplicationTest.java +++ b/spring-test-context-caching-introduction/src/test/java/de/rieckpil/blog/SecondApplicationTest.java @@ -1,30 +1,27 @@ package de.rieckpil.blog; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.when; +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; + import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.boot.test.web.client.TestRestTemplate; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.mockito.Mockito.when; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - @SpringBootTest(webEnvironment = RANDOM_PORT) public class SecondApplicationTest { - @Autowired - private TestRestTemplate testRestTemplate; + @Autowired private TestRestTemplate testRestTemplate; - @MockBean - private PersonService personService; + @MockBean private PersonService personService; @Test public void testPublicEndpoint() { when(personService.getPerson()).thenReturn("testPerson"); - String result = this.testRestTemplate - .getForObject("/", String.class); + String result = this.testRestTemplate.getForObject("/", String.class); assertEquals("testPerson", result); } diff --git a/spring-test-context-caching-introduction/src/test/java/de/rieckpil/blog/ThirdApplicationContext.java b/spring-test-context-caching-introduction/src/test/java/de/rieckpil/blog/ThirdApplicationContext.java index 71dd9c59..93c1953b 100644 --- a/spring-test-context-caching-introduction/src/test/java/de/rieckpil/blog/ThirdApplicationContext.java +++ b/spring-test-context-caching-introduction/src/test/java/de/rieckpil/blog/ThirdApplicationContext.java @@ -1,5 +1,9 @@ package de.rieckpil.blog; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.when; +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; + import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @@ -7,26 +11,19 @@ import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.test.context.TestPropertySource; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.mockito.Mockito.when; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - @SpringBootTest(webEnvironment = RANDOM_PORT) @TestPropertySource(properties = "secret_value=foo") public class ThirdApplicationContext { - @Autowired - private TestRestTemplate testRestTemplate; + @Autowired private TestRestTemplate testRestTemplate; - @MockBean - private PersonService personService; + @MockBean private PersonService personService; @Test public void testPublicEndpoint() { when(personService.getPerson()).thenReturn("testPerson"); - String result = this.testRestTemplate - .getForObject("/", String.class); + String result = this.testRestTemplate.getForObject("/", String.class); assertEquals("testPerson", result); } diff --git a/spring-web-client-customizing/pom.xml b/spring-web-client-customizing/pom.xml index 34b6fa24..b93f2e3c 100644 --- a/spring-web-client-customizing/pom.xml +++ b/spring-web-client-customizing/pom.xml @@ -4,22 +4,17 @@ 4.0.0 - org.springframework.boot - spring-boot-starter-parent - 2.5.3 - + de.rieckpil.blog + blog-parent + 0.0.1-SNAPSHOT + ../pom.xml - de.rieckpil.blog spring-web-client-customizing 0.0.1-SNAPSHOT spring-web-client-customizing Customize Spring WebClient - - 11 - - org.springframework.boot diff --git a/spring-web-client-customizing/src/main/java/de/rieckpil/blog/Application.java b/spring-web-client-customizing/src/main/java/de/rieckpil/blog/Application.java index bd5e4c56..6511f3c1 100644 --- a/spring-web-client-customizing/src/main/java/de/rieckpil/blog/Application.java +++ b/spring-web-client-customizing/src/main/java/de/rieckpil/blog/Application.java @@ -9,5 +9,4 @@ public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } - } diff --git a/spring-web-client-customizing/src/main/java/de/rieckpil/blog/RandomDataController.java b/spring-web-client-customizing/src/main/java/de/rieckpil/blog/RandomDataController.java index 8288250d..ec9b9683 100644 --- a/spring-web-client-customizing/src/main/java/de/rieckpil/blog/RandomDataController.java +++ b/spring-web-client-customizing/src/main/java/de/rieckpil/blog/RandomDataController.java @@ -18,11 +18,6 @@ public RandomDataController(WebClient.Builder webClientBuilder) { @GetMapping public JsonNode getRandomData() { - return webClient - .get() - .uri("/todos") - .retrieve() - .bodyToMono(JsonNode.class) - .block(); + return webClient.get().uri("/todos").retrieve().bodyToMono(JsonNode.class).block(); } } diff --git a/spring-web-client-customizing/src/main/java/de/rieckpil/blog/ResponseLoggingCustomizer.java b/spring-web-client-customizing/src/main/java/de/rieckpil/blog/ResponseLoggingCustomizer.java index 191f10ed..7c8400bc 100644 --- a/spring-web-client-customizing/src/main/java/de/rieckpil/blog/ResponseLoggingCustomizer.java +++ b/spring-web-client-customizing/src/main/java/de/rieckpil/blog/ResponseLoggingCustomizer.java @@ -1,5 +1,6 @@ package de.rieckpil.blog; +import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.web.reactive.function.client.WebClientCustomizer; @@ -8,8 +9,6 @@ import org.springframework.web.reactive.function.client.WebClient; import reactor.core.publisher.Mono; -import java.util.List; - @Component public class ResponseLoggingCustomizer implements WebClientCustomizer { @@ -22,13 +21,17 @@ public void customize(WebClient.Builder webClientBuilder) { } private ExchangeFilterFunction logResponse() { - return ExchangeFilterFunction.ofResponseProcessor(clientResponse -> { - logger.info("Response: {}", clientResponse.statusCode()); - logger.info("--- Http Headers of Response: ---"); - clientResponse.headers().asHttpHeaders() - .forEach((name, values) -> values.forEach(value -> logger.info("{}={}", name, value))); - return Mono.just(clientResponse); - }); + return ExchangeFilterFunction.ofResponseProcessor( + clientResponse -> { + logger.info("Response: {}", clientResponse.statusCode()); + logger.info("--- Http Headers of Response: ---"); + clientResponse + .headers() + .asHttpHeaders() + .forEach( + (name, values) -> values.forEach(value -> logger.info("{}={}", name, value))); + return Mono.just(clientResponse); + }); } private ExchangeFilterFunction logRequest() { diff --git a/spring-web-client-customizing/src/test/java/de/rieckpil/blog/ApplicationTests.java b/spring-web-client-customizing/src/test/java/de/rieckpil/blog/ApplicationTests.java index 874de1b2..4f1f1cf4 100644 --- a/spring-web-client-customizing/src/test/java/de/rieckpil/blog/ApplicationTests.java +++ b/spring-web-client-customizing/src/test/java/de/rieckpil/blog/ApplicationTests.java @@ -7,7 +7,5 @@ class ApplicationTests { @Test - void contextLoads() { - } - + void contextLoads() {} } diff --git a/spring-web-client-demo/pom.xml b/spring-web-client-demo/pom.xml index 074066ee..c1af5110 100644 --- a/spring-web-client-demo/pom.xml +++ b/spring-web-client-demo/pom.xml @@ -4,20 +4,18 @@ 4.0.0 - org.springframework.boot - spring-boot-starter-parent - 2.4.5 - + de.rieckpil.blog + blog-parent + 0.0.1-SNAPSHOT + ../pom.xml - de.rieckpil.blog spring-web-client-demo 0.0.1-SNAPSHOT spring-web-client-demo Demo project for Spring Boot - 11 4.8.0 4.8.0 diff --git a/spring-web-client-demo/src/main/java/de/rieckpil/blog/Application.java b/spring-web-client-demo/src/main/java/de/rieckpil/blog/Application.java index bd5e4c56..6511f3c1 100644 --- a/spring-web-client-demo/src/main/java/de/rieckpil/blog/Application.java +++ b/spring-web-client-demo/src/main/java/de/rieckpil/blog/Application.java @@ -9,5 +9,4 @@ public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } - } diff --git a/spring-web-client-demo/src/main/java/de/rieckpil/blog/CustomerController.java b/spring-web-client-demo/src/main/java/de/rieckpil/blog/CustomerController.java index 2cedd9e4..9101beb3 100644 --- a/spring-web-client-demo/src/main/java/de/rieckpil/blog/CustomerController.java +++ b/spring-web-client-demo/src/main/java/de/rieckpil/blog/CustomerController.java @@ -19,8 +19,6 @@ public CustomerController(ObjectMapper objectMapper) { @GetMapping(path = "/{id}") public JsonNode getCustomerById(@PathVariable("id") Long id) { - return objectMapper.createObjectNode() - .put("name", "duke") - .put("customerId", id); + return objectMapper.createObjectNode().put("name", "duke").put("customerId", id); } } diff --git a/spring-web-client-demo/src/main/java/de/rieckpil/blog/SimpleApiClient.java b/spring-web-client-demo/src/main/java/de/rieckpil/blog/SimpleApiClient.java index 63090166..43d3fb18 100644 --- a/spring-web-client-demo/src/main/java/de/rieckpil/blog/SimpleApiClient.java +++ b/spring-web-client-demo/src/main/java/de/rieckpil/blog/SimpleApiClient.java @@ -2,15 +2,14 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; -import org.springframework.http.HttpStatus; +import java.time.Duration; +import org.springframework.http.HttpStatusCode; import org.springframework.stereotype.Service; import org.springframework.web.reactive.function.BodyInserters; import org.springframework.web.reactive.function.client.WebClient; import reactor.core.publisher.Mono; import reactor.util.retry.Retry; -import java.time.Duration; - @Service public class SimpleApiClient { @@ -24,36 +23,47 @@ public SimpleApiClient(WebClient defaultWebClient, ObjectMapper objectMapper) { } public JsonNode getTodoFromAPI() { - return this.defaultWebClient.get().uri("/todos/1") - .retrieve() - .onStatus(HttpStatus::is4xxClientError, response -> { - System.out.println("4xx error"); - return Mono.error(new RuntimeException("4xx")); - }) - .onStatus(HttpStatus::is5xxServerError, response -> { - System.out.println("5xx error"); - return Mono.error(new RuntimeException("5xx")); - }) - .bodyToMono(JsonNode.class) - .block(); + return this.defaultWebClient + .get() + .uri("/todos/1") + .retrieve() + .onStatus( + HttpStatusCode::is4xxClientError, + response -> { + System.out.println("4xx error"); + return Mono.error(new RuntimeException("4xx")); + }) + .onStatus( + HttpStatusCode::is5xxServerError, + response -> { + System.out.println("5xx error"); + return Mono.error(new RuntimeException("5xx")); + }) + .bodyToMono(JsonNode.class) + .block(); } public JsonNode getRetryTodoFromAPI() { - return this.defaultWebClient.get().uri("/todos/1") - .retrieve() - .bodyToMono(JsonNode.class) - .retryWhen(Retry.max(5)) - .timeout(Duration.ofSeconds(2), Mono.just(objectMapper.createObjectNode().put("message", "fallback"))) - .block(); + return this.defaultWebClient + .get() + .uri("/todos/1") + .retrieve() + .bodyToMono(JsonNode.class) + .retryWhen(Retry.max(5)) + .timeout( + Duration.ofSeconds(2), + Mono.just(objectMapper.createObjectNode().put("message", "fallback"))) + .block(); } public JsonNode postToTodoAPI() { return this.defaultWebClient - .post() - .uri("/todos") - .body(BodyInserters.fromValue("{ \"title\": \"foo\", \"body\": \"bar\", \"userId\": \"1\"}")) - .retrieve() - .bodyToMono(JsonNode.class) - .block(); + .post() + .uri("/todos") + .body( + BodyInserters.fromValue("{ \"title\": \"foo\", \"body\": \"bar\", \"userId\": \"1\"}")) + .retrieve() + .bodyToMono(JsonNode.class) + .block(); } } diff --git a/spring-web-client-demo/src/main/java/de/rieckpil/blog/SimpleWebClientConfiguration.java b/spring-web-client-demo/src/main/java/de/rieckpil/blog/SimpleWebClientConfiguration.java index 0c3e741f..e81e8cd7 100644 --- a/spring-web-client-demo/src/main/java/de/rieckpil/blog/SimpleWebClientConfiguration.java +++ b/spring-web-client-demo/src/main/java/de/rieckpil/blog/SimpleWebClientConfiguration.java @@ -3,6 +3,9 @@ import io.netty.channel.ChannelOption; import io.netty.handler.timeout.ReadTimeoutHandler; import io.netty.handler.timeout.WriteTimeoutHandler; +import java.util.List; +import java.util.UUID; +import java.util.function.Function; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.annotation.Bean; @@ -16,11 +19,6 @@ import org.springframework.web.reactive.function.client.WebClient; import reactor.core.publisher.Mono; import reactor.netty.http.client.HttpClient; -import reactor.netty.tcp.TcpClient; - -import java.util.List; -import java.util.UUID; -import java.util.function.Function; @Component public class SimpleWebClientConfiguration { @@ -31,49 +29,55 @@ public class SimpleWebClientConfiguration { // @Bean public WebClient webClientFromBuilder(WebClient.Builder webClientBuilder) { - HttpClient httpClient = HttpClient.create() - .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 2_000) // millis - .doOnConnected(connection -> - connection - .addHandlerLast(new ReadTimeoutHandler(2)) // seconds - .addHandlerLast(new WriteTimeoutHandler(2))); // seconds + HttpClient httpClient = + HttpClient.create() + .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 2_000) // millis + .doOnConnected( + connection -> + connection + .addHandlerLast(new ReadTimeoutHandler(2)) // seconds + .addHandlerLast(new WriteTimeoutHandler(2))); // seconds return webClientBuilder - .baseUrl(BASE_URL) - .clientConnector(new ReactorClientHttpConnector(httpClient)) - .defaultCookie("cookieKey", "cookieValue", "teapot", "amsterdam") - .defaultCookie("secretToken", UUID.randomUUID().toString()) - .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) - .defaultHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE) - .defaultHeader(HttpHeaders.USER_AGENT, "I'm a teapot") - .filter(ExchangeFilterFunctions.basicAuthentication("rieckpil", UUID.randomUUID().toString())) - .filter(logRequest()) - .filter(logResponse()) - .build(); + .baseUrl(BASE_URL) + .clientConnector(new ReactorClientHttpConnector(httpClient)) + .defaultCookie("cookieKey", "cookieValue", "teapot", "amsterdam") + .defaultCookie("secretToken", UUID.randomUUID().toString()) + .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) + .defaultHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE) + .defaultHeader(HttpHeaders.USER_AGENT, "I'm a teapot") + .filter( + ExchangeFilterFunctions.basicAuthentication("rieckpil", UUID.randomUUID().toString())) + .filter(logRequest()) + .filter(logResponse()) + .build(); } @Bean public WebClient webClientFromScratch() { - HttpClient httpClient = HttpClient.create() - .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 2_000) // millis - .doOnConnected(connection -> - connection - .addHandlerLast(new ReadTimeoutHandler(2)) // seconds - .addHandlerLast(new WriteTimeoutHandler(2))); // seconds + HttpClient httpClient = + HttpClient.create() + .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 2_000) // millis + .doOnConnected( + connection -> + connection + .addHandlerLast(new ReadTimeoutHandler(2)) // seconds + .addHandlerLast(new WriteTimeoutHandler(2))); // seconds return WebClient.builder() - .baseUrl(BASE_URL) - .clientConnector(new ReactorClientHttpConnector(httpClient)) - .defaultCookie("cookieKey", "cookieValue", "teapot", "amsterdam") - .defaultCookie("secretToken", UUID.randomUUID().toString()) - .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) - .defaultHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE) - .defaultHeader(HttpHeaders.USER_AGENT, "I'm a teapot") - .filter(ExchangeFilterFunctions.basicAuthentication("rieckpil", UUID.randomUUID().toString())) - .filter(logRequest()) - .filter(logResponse()) - .build(); + .baseUrl(BASE_URL) + .clientConnector(new ReactorClientHttpConnector(httpClient)) + .defaultCookie("cookieKey", "cookieValue", "teapot", "amsterdam") + .defaultCookie("secretToken", UUID.randomUUID().toString()) + .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) + .defaultHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE) + .defaultHeader(HttpHeaders.USER_AGENT, "I'm a teapot") + .filter( + ExchangeFilterFunctions.basicAuthentication("rieckpil", UUID.randomUUID().toString())) + .filter(logRequest()) + .filter(logResponse()) + .build(); } private ExchangeFilterFunction logRequest() { @@ -88,18 +92,27 @@ private ExchangeFilterFunction logRequest() { } private ExchangeFilterFunction authHeader(Function token) { - return (request, next) -> next.exchange(ClientRequest.from(request).headers((headers) -> { - headers.setBearerAuth(token.apply("xyz")); - }).build()); + return (request, next) -> + next.exchange( + ClientRequest.from(request) + .headers( + (headers) -> { + headers.setBearerAuth(token.apply("xyz")); + }) + .build()); } private ExchangeFilterFunction logResponse() { - return ExchangeFilterFunction.ofResponseProcessor(clientResponse -> { - logger.info("Response: {}", clientResponse.statusCode()); - clientResponse.headers().asHttpHeaders() - .forEach((name, values) -> values.forEach(value -> logger.info("{}={}", name, value))); - return Mono.just(clientResponse); - }); + return ExchangeFilterFunction.ofResponseProcessor( + clientResponse -> { + logger.info("Response: {}", clientResponse.statusCode()); + clientResponse + .headers() + .asHttpHeaders() + .forEach( + (name, values) -> values.forEach(value -> logger.info("{}={}", name, value))); + return Mono.just(clientResponse); + }); } private void logHeader(String name, List values) { diff --git a/spring-web-client-demo/src/test/java/de/rieckpil/blog/ApplicationTests.java b/spring-web-client-demo/src/test/java/de/rieckpil/blog/ApplicationTests.java index 50e12cfb..4f1f1cf4 100644 --- a/spring-web-client-demo/src/test/java/de/rieckpil/blog/ApplicationTests.java +++ b/spring-web-client-demo/src/test/java/de/rieckpil/blog/ApplicationTests.java @@ -7,6 +7,5 @@ class ApplicationTests { @Test - void contextLoads() { - } + void contextLoads() {} } diff --git a/spring-web-client-demo/src/test/java/de/rieckpil/blog/CustomerControllerIT.java b/spring-web-client-demo/src/test/java/de/rieckpil/blog/CustomerControllerIT.java index 0b18062d..0c1cc164 100644 --- a/spring-web-client-demo/src/test/java/de/rieckpil/blog/CustomerControllerIT.java +++ b/spring-web-client-demo/src/test/java/de/rieckpil/blog/CustomerControllerIT.java @@ -9,17 +9,23 @@ @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) class CustomerControllerIT { - @Autowired - private WebTestClient webTestClient; + @Autowired private WebTestClient webTestClient; @Test void shouldReturnCustomerOne() { - this.webTestClient.get().uri("/api/customers/1") // the base URL is already configured for us - .accept(MediaType.APPLICATION_JSON) - .exchange().expectStatus().isOk() - .expectHeader().contentType(MediaType.APPLICATION_JSON) - .expectBody() - .jsonPath("$.customerId").isNotEmpty() - .jsonPath("$.name").isNotEmpty(); + this.webTestClient + .get() + .uri("/api/customers/1") // the base URL is already configured for us + .accept(MediaType.APPLICATION_JSON) + .exchange() + .expectStatus() + .isOk() + .expectHeader() + .contentType(MediaType.APPLICATION_JSON) + .expectBody() + .jsonPath("$.customerId") + .isNotEmpty() + .jsonPath("$.name") + .isNotEmpty(); } } diff --git a/spring-web-client-demo/src/test/java/de/rieckpil/blog/SimpleApiClientTest.java b/spring-web-client-demo/src/test/java/de/rieckpil/blog/SimpleApiClientTest.java index 03d96396..174181ed 100644 --- a/spring-web-client-demo/src/test/java/de/rieckpil/blog/SimpleApiClientTest.java +++ b/spring-web-client-demo/src/test/java/de/rieckpil/blog/SimpleApiClientTest.java @@ -1,7 +1,10 @@ package de.rieckpil.blog; +import static org.junit.jupiter.api.Assertions.assertEquals; + import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.IOException; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import okhttp3.mockwebserver.RecordedRequest; @@ -9,10 +12,6 @@ import org.junit.jupiter.api.Test; import org.springframework.web.reactive.function.client.WebClient; -import java.io.IOException; - -import static org.junit.jupiter.api.Assertions.assertEquals; - class SimpleApiClientTest { private MockWebServer mockWebServer; @@ -22,16 +21,18 @@ class SimpleApiClientTest { void setup() throws IOException { this.mockWebServer = new MockWebServer(); this.mockWebServer.start(); - this.cut = new SimpleApiClient(WebClient - .builder() - .baseUrl(mockWebServer.url("/").toString()).build(), new ObjectMapper()); + this.cut = + new SimpleApiClient( + WebClient.builder().baseUrl(mockWebServer.url("/").toString()).build(), + new ObjectMapper()); } @Test void testGetUserById() throws InterruptedException { - MockResponse mockResponse = new MockResponse() - .addHeader("Content-Type", "application/json; charset=utf-8") - .setBody("{\"id\": 1, \"name\":\"write good tests\"}"); + MockResponse mockResponse = + new MockResponse() + .addHeader("Content-Type", "application/json; charset=utf-8") + .setBody("{\"id\": 1, \"name\":\"write good tests\"}"); mockWebServer.enqueue(mockResponse); diff --git a/spring-web-client-exchange-retrieve/pom.xml b/spring-web-client-exchange-retrieve/pom.xml index 084ab044..494ceef7 100644 --- a/spring-web-client-exchange-retrieve/pom.xml +++ b/spring-web-client-exchange-retrieve/pom.xml @@ -4,20 +4,18 @@ 4.0.0 - org.springframework.boot - spring-boot-starter-parent - 2.4.0 - + de.rieckpil.blog + blog-parent + 0.0.1-SNAPSHOT + ../pom.xml - de.rieckpil.blog spring-web-client-exchange-retrieve 0.0.1-SNAPSHOT spring-web-client-exchange-retrieve Spring WebClient exchange vs. retrieve - 11 2.27.1 @@ -38,7 +36,7 @@ com.github.tomakehurst - wiremock-jre8 + wiremock-standalone ${wiremock.version} test diff --git a/spring-web-client-exchange-retrieve/src/main/java/de/rieckpil/blog/Application.java b/spring-web-client-exchange-retrieve/src/main/java/de/rieckpil/blog/Application.java index f1eb68af..d245e7b1 100644 --- a/spring-web-client-exchange-retrieve/src/main/java/de/rieckpil/blog/Application.java +++ b/spring-web-client-exchange-retrieve/src/main/java/de/rieckpil/blog/Application.java @@ -12,7 +12,10 @@ public class Application implements CommandLineRunner { private final RetrieveWebClient retrieveWebClient; private final ObjectMapper objectMapper; - public Application(ExchangeWebClient exchangeWebClient, RetrieveWebClient retrieveWebClient, ObjectMapper objectMapper) { + public Application( + ExchangeWebClient exchangeWebClient, + RetrieveWebClient retrieveWebClient, + ObjectMapper objectMapper) { this.exchangeWebClient = exchangeWebClient; this.retrieveWebClient = retrieveWebClient; this.objectMapper = objectMapper; @@ -27,12 +30,12 @@ public void run(String... args) throws Exception { System.out.println(retrieveWebClient.getTodos()); System.out.println(exchangeWebClient.getTodos()); - System.out.println(exchangeWebClient.createTodo(objectMapper - .createObjectNode() - .put("task", "learn Spring Boot"))); + System.out.println( + exchangeWebClient.createTodo( + objectMapper.createObjectNode().put("task", "learn Spring Boot"))); - System.out.println(retrieveWebClient.createTodo(objectMapper - .createObjectNode() - .put("task", "learn Spring Boot"))); + System.out.println( + retrieveWebClient.createTodo( + objectMapper.createObjectNode().put("task", "learn Spring Boot"))); } } diff --git a/spring-web-client-exchange-retrieve/src/main/java/de/rieckpil/blog/ExchangeWebClient.java b/spring-web-client-exchange-retrieve/src/main/java/de/rieckpil/blog/ExchangeWebClient.java index e3933431..5da83cc0 100644 --- a/spring-web-client-exchange-retrieve/src/main/java/de/rieckpil/blog/ExchangeWebClient.java +++ b/spring-web-client-exchange-retrieve/src/main/java/de/rieckpil/blog/ExchangeWebClient.java @@ -17,31 +17,37 @@ public ExchangeWebClient(WebClient jsonPlaceholderWebClient) { } public JsonNode getTodo(String id) { - return this.jsonPlaceholderWebClient.get() - .uri("/todos/{id}", id) - .exchange() - .flatMap(clientResponse -> clientResponse.bodyToMono(JsonNode.class)) - .block(); + return this.jsonPlaceholderWebClient + .get() + .uri("/todos/{id}", id) + .exchange() + .flatMap(clientResponse -> clientResponse.bodyToMono(JsonNode.class)) + .block(); } public JsonNode getTodos() { - return this.jsonPlaceholderWebClient.get() - .uri("/todos") - .exchange() - .flatMap(clientResponse -> clientResponse.bodyToMono(JsonNode.class)) - .block(); + return this.jsonPlaceholderWebClient + .get() + .uri("/todos") + .exchange() + .flatMap(clientResponse -> clientResponse.bodyToMono(JsonNode.class)) + .block(); } public boolean createTodo(JsonNode payload) { - ClientResponse response = this.jsonPlaceholderWebClient - .post() - .uri("/todos") - .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) - .bodyValue(payload) - .exchange() - .doOnSuccess(clientResponse -> - System.out.println("Location header: " + clientResponse.headers().header(HttpHeaders.LOCATION))) - .block(); + ClientResponse response = + this.jsonPlaceholderWebClient + .post() + .uri("/todos") + .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) + .bodyValue(payload) + .exchange() + .doOnSuccess( + clientResponse -> + System.out.println( + "Location header: " + + clientResponse.headers().header(HttpHeaders.LOCATION))) + .block(); if (response.statusCode().value() == 201) { return !response.headers().header(HttpHeaders.LOCATION).isEmpty(); @@ -49,5 +55,4 @@ public boolean createTodo(JsonNode payload) { return false; } } - } diff --git a/spring-web-client-exchange-retrieve/src/main/java/de/rieckpil/blog/RetrieveWebClient.java b/spring-web-client-exchange-retrieve/src/main/java/de/rieckpil/blog/RetrieveWebClient.java index 811cd08c..d0935572 100644 --- a/spring-web-client-exchange-retrieve/src/main/java/de/rieckpil/blog/RetrieveWebClient.java +++ b/spring-web-client-exchange-retrieve/src/main/java/de/rieckpil/blog/RetrieveWebClient.java @@ -2,7 +2,7 @@ import com.fasterxml.jackson.databind.JsonNode; import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; +import org.springframework.http.HttpStatusCode; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Component; @@ -19,32 +19,41 @@ public RetrieveWebClient(WebClient jsonPlaceholderWebClient) { } public JsonNode getTodo(String id) { - return this.jsonPlaceholderWebClient.get() - .uri("/todos/{id}", id) - .retrieve() - .onStatus(HttpStatus::is4xxClientError, response -> response.rawStatusCode() == 418 ? Mono.empty() : Mono.error(new RuntimeException("Error"))) - .onStatus(HttpStatus::is5xxServerError, response -> Mono.error(new RuntimeException("Error"))) - .bodyToMono(JsonNode.class) - .block(); + return this.jsonPlaceholderWebClient + .get() + .uri("/todos/{id}", id) + .retrieve() + .onStatus( + HttpStatusCode::is4xxClientError, + response -> + response.statusCode().value() == 418 + ? Mono.empty() + : Mono.error(new RuntimeException("Error"))) + .onStatus( + HttpStatusCode::is5xxServerError, response -> Mono.error(new RuntimeException("Error"))) + .bodyToMono(JsonNode.class) + .block(); } public JsonNode getTodos() { - return this.jsonPlaceholderWebClient.get() - .uri("/todos") - .retrieve() - .bodyToMono(JsonNode.class) - .block(); + return this.jsonPlaceholderWebClient + .get() + .uri("/todos") + .retrieve() + .bodyToMono(JsonNode.class) + .block(); } public boolean createTodo(JsonNode payload) { - ResponseEntity response = this.jsonPlaceholderWebClient - .post() - .uri("/todos") - .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) - .bodyValue(payload) - .retrieve() - .toEntity(JsonNode.class) - .block(); + ResponseEntity response = + this.jsonPlaceholderWebClient + .post() + .uri("/todos") + .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) + .bodyValue(payload) + .retrieve() + .toEntity(JsonNode.class) + .block(); response.getHeaders().forEach((key, value) -> System.out.println(key + ":" + value)); diff --git a/spring-web-client-exchange-retrieve/src/main/java/de/rieckpil/blog/WebClientConfig.java b/spring-web-client-exchange-retrieve/src/main/java/de/rieckpil/blog/WebClientConfig.java index 11a6a5a0..aa67f3cb 100644 --- a/spring-web-client-exchange-retrieve/src/main/java/de/rieckpil/blog/WebClientConfig.java +++ b/spring-web-client-exchange-retrieve/src/main/java/de/rieckpil/blog/WebClientConfig.java @@ -1,5 +1,7 @@ package de.rieckpil.blog; +import static io.netty.channel.ChannelOption.CONNECT_TIMEOUT_MILLIS; + import io.netty.handler.timeout.ReadTimeoutHandler; import io.netty.handler.timeout.WriteTimeoutHandler; import org.springframework.beans.factory.annotation.Value; @@ -10,8 +12,6 @@ import reactor.netty.http.client.HttpClient; import reactor.netty.tcp.TcpClient; -import static io.netty.channel.ChannelOption.CONNECT_TIMEOUT_MILLIS; - @Configuration public class WebClientConfig { @@ -19,19 +19,20 @@ public class WebClientConfig { @Bean public WebClient jsonPlaceholderWebClient( - @Value("${todo_url}") String todoBaseUrl, - WebClient.Builder webClientBuilder) { + @Value("${todo_url}") String todoBaseUrl, WebClient.Builder webClientBuilder) { - TcpClient tcpClient = TcpClient.create() - .option(CONNECT_TIMEOUT_MILLIS, TIMEOUT_IN_SECONDS * 1000) - .doOnConnected(connection -> - connection - .addHandlerLast(new ReadTimeoutHandler(TIMEOUT_IN_SECONDS)) - .addHandlerLast(new WriteTimeoutHandler(TIMEOUT_IN_SECONDS))); + TcpClient tcpClient = + TcpClient.create() + .option(CONNECT_TIMEOUT_MILLIS, TIMEOUT_IN_SECONDS * 1000) + .doOnConnected( + connection -> + connection + .addHandlerLast(new ReadTimeoutHandler(TIMEOUT_IN_SECONDS)) + .addHandlerLast(new WriteTimeoutHandler(TIMEOUT_IN_SECONDS))); return webClientBuilder - .clientConnector(new ReactorClientHttpConnector(HttpClient.from(tcpClient))) - .baseUrl(todoBaseUrl) - .build(); + .clientConnector(new ReactorClientHttpConnector(HttpClient.from(tcpClient))) + .baseUrl(todoBaseUrl) + .build(); } } diff --git a/spring-web-client-exchange-retrieve/src/test/java/de/rieckpil/blog/ApplicationTests.java b/spring-web-client-exchange-retrieve/src/test/java/de/rieckpil/blog/ApplicationTests.java index 8471832e..fbfbd938 100644 --- a/spring-web-client-exchange-retrieve/src/test/java/de/rieckpil/blog/ApplicationTests.java +++ b/spring-web-client-exchange-retrieve/src/test/java/de/rieckpil/blog/ApplicationTests.java @@ -9,7 +9,5 @@ class ApplicationTests { @Test - void contextLoads() { - } - + void contextLoads() {} } diff --git a/spring-web-client-exchange-retrieve/src/test/java/de/rieckpil/blog/WireMockInitializer.java b/spring-web-client-exchange-retrieve/src/test/java/de/rieckpil/blog/WireMockInitializer.java index 0439b350..fc160aa2 100644 --- a/spring-web-client-exchange-retrieve/src/test/java/de/rieckpil/blog/WireMockInitializer.java +++ b/spring-web-client-exchange-retrieve/src/test/java/de/rieckpil/blog/WireMockInitializer.java @@ -1,5 +1,7 @@ package de.rieckpil.blog; +import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; + import com.github.tomakehurst.wiremock.WireMockServer; import com.github.tomakehurst.wiremock.client.WireMock; import com.github.tomakehurst.wiremock.core.WireMockConfiguration; @@ -9,41 +11,43 @@ import org.springframework.context.event.ContextClosedEvent; import org.springframework.http.MediaType; -import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; - -public class WireMockInitializer implements ApplicationContextInitializer { +public class WireMockInitializer + implements ApplicationContextInitializer { @Override public void initialize(ConfigurableApplicationContext configurableApplicationContext) { WireMockServer wireMockServer = new WireMockServer(new WireMockConfiguration().dynamicPort()); wireMockServer.start(); - configurableApplicationContext.getBeanFactory().registerSingleton("wireMockServer", wireMockServer); + configurableApplicationContext + .getBeanFactory() + .registerSingleton("wireMockServer", wireMockServer); - configurableApplicationContext.addApplicationListener(applicationEvent -> { - if (applicationEvent instanceof ContextClosedEvent) { - wireMockServer.stop(); - } - }); + configurableApplicationContext.addApplicationListener( + applicationEvent -> { + if (applicationEvent instanceof ContextClosedEvent) { + wireMockServer.stop(); + } + }); - TestPropertyValues - .of("todo_url:http://localhost:" + wireMockServer.port() + "/") - .applyTo(configurableApplicationContext); + TestPropertyValues.of("todo_url:http://localhost:" + wireMockServer.port() + "/") + .applyTo(configurableApplicationContext); wireMockServer.stubFor( - WireMock.get("/todos") - .willReturn(aResponse() - .withHeader("Content-Type", MediaType.APPLICATION_JSON_VALUE) - .withBody("[{\"userId\": 1,\"id\": 1,\"title\": \"Learn Spring Boot 3.0\", \"completed\": false}," + - "{\"userId\": 1,\"id\": 2,\"title\": \"Learn WireMock\", \"completed\": true}]")) - ); + WireMock.get("/todos") + .willReturn( + aResponse() + .withHeader("Content-Type", MediaType.APPLICATION_JSON_VALUE) + .withBody( + "[{\"userId\": 1,\"id\": 1,\"title\": \"Learn Spring Boot 3.0\", \"completed\": false}," + + "{\"userId\": 1,\"id\": 2,\"title\": \"Learn WireMock\", \"completed\": true}]"))); wireMockServer.stubFor( - WireMock.post("/todos") - .willReturn(aResponse() - .withStatus(201) - .withHeader("Location", "http://localhost:" + wireMockServer.port() + "/todos42")) - ); - + WireMock.post("/todos") + .willReturn( + aResponse() + .withStatus(201) + .withHeader( + "Location", "http://localhost:" + wireMockServer.port() + "/todos42"))); } } diff --git a/spring-web-client-expose-metrics/pom.xml b/spring-web-client-expose-metrics/pom.xml index 01a88a00..47848005 100644 --- a/spring-web-client-expose-metrics/pom.xml +++ b/spring-web-client-expose-metrics/pom.xml @@ -2,23 +2,19 @@ 4.0.0 + - org.springframework.boot - spring-boot-starter-parent - 2.5.3 - + de.rieckpil.blog + blog-parent + 0.0.1-SNAPSHOT + ../pom.xml - de.rieckpil.blog spring-web-client-expose-metrics 0.0.1-SNAPSHOT spring-web-client-expose-metrics Spring WebClient Expose Metrics - - 11 - - org.springframework.boot diff --git a/spring-web-client-expose-metrics/src/main/java/de/rieckpil/blog/RandomQuoteClient.java b/spring-web-client-expose-metrics/src/main/java/de/rieckpil/blog/RandomQuoteClient.java index 5c5ed75c..dba6bd04 100644 --- a/spring-web-client-expose-metrics/src/main/java/de/rieckpil/blog/RandomQuoteClient.java +++ b/spring-web-client-expose-metrics/src/main/java/de/rieckpil/blog/RandomQuoteClient.java @@ -15,10 +15,10 @@ public RandomQuoteClient(WebClient webClient) { public JsonNode fetchRandomQuotes() { return webClient - .get() - .uri("https://quotes.rest/qod") - .retrieve() - .bodyToMono(JsonNode.class) - .block(); + .get() + .uri("https://quotes.rest/qod") + .retrieve() + .bodyToMono(JsonNode.class) + .block(); } } diff --git a/spring-web-client-expose-metrics/src/main/java/de/rieckpil/blog/RandomUserClient.java b/spring-web-client-expose-metrics/src/main/java/de/rieckpil/blog/RandomUserClient.java index 164306bc..2d1ad35d 100644 --- a/spring-web-client-expose-metrics/src/main/java/de/rieckpil/blog/RandomUserClient.java +++ b/spring-web-client-expose-metrics/src/main/java/de/rieckpil/blog/RandomUserClient.java @@ -15,10 +15,10 @@ public RandomUserClient(WebClient webClient) { public JsonNode getRandomUserById(int id) { return webClient - .get() - .uri("https://jsonplaceholder.typicode.com/todos/{id}", id) - .retrieve() - .bodyToMono(JsonNode.class) - .block(); + .get() + .uri("https://jsonplaceholder.typicode.com/todos/{id}", id) + .retrieve() + .bodyToMono(JsonNode.class) + .block(); } } diff --git a/spring-web-client-expose-metrics/src/main/java/de/rieckpil/blog/WebClientConfiguration.java b/spring-web-client-expose-metrics/src/main/java/de/rieckpil/blog/WebClientConfiguration.java index b0c381bd..82028648 100644 --- a/spring-web-client-expose-metrics/src/main/java/de/rieckpil/blog/WebClientConfiguration.java +++ b/spring-web-client-expose-metrics/src/main/java/de/rieckpil/blog/WebClientConfiguration.java @@ -15,15 +15,18 @@ public class WebClientConfiguration { @Bean public WebClient webClient(WebClient.Builder webClientBuilder) { - HttpClient httpClient = HttpClient.create() - .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 4_000) - .doOnConnected(connection -> - connection.addHandlerLast(new ReadTimeoutHandler(4)) - .addHandlerLast(new WriteTimeoutHandler(4))); + HttpClient httpClient = + HttpClient.create() + .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 4_000) + .doOnConnected( + connection -> + connection + .addHandlerLast(new ReadTimeoutHandler(4)) + .addHandlerLast(new WriteTimeoutHandler(4))); return webClientBuilder - .defaultHeader(HttpHeaders.USER_AGENT, "SAMPLE_APP") - .clientConnector(new ReactorClientHttpConnector(httpClient)) - .build(); + .defaultHeader(HttpHeaders.USER_AGENT, "SAMPLE_APP") + .clientConnector(new ReactorClientHttpConnector(httpClient)) + .build(); } } diff --git a/spring-web-client-oauth2-reactive-stack/pom.xml b/spring-web-client-oauth2-reactive-stack/pom.xml index 5ec79490..0663bece 100644 --- a/spring-web-client-oauth2-reactive-stack/pom.xml +++ b/spring-web-client-oauth2-reactive-stack/pom.xml @@ -2,22 +2,18 @@ 4.0.0 - - org.springframework.boot - spring-boot-starter-parent - 2.2.2.RELEASE - - + de.rieckpil.blog + blog-parent + 0.0.1-SNAPSHOT + ../pom.xml + + spring-web-client-oauth2-reactive-stack 0.0.1-SNAPSHOT spring-web-client-oauth2-reactive-stack - - 11 - - org.springframework.boot @@ -40,12 +36,6 @@ org.springframework.boot spring-boot-starter-test test - - - org.junit.vintage - junit-vintage-engine - - io.projectreactor diff --git a/spring-web-client-oauth2-reactive-stack/src/main/java/de/rieckpil/blog/GitHubController.java b/spring-web-client-oauth2-reactive-stack/src/main/java/de/rieckpil/blog/GitHubController.java index f2c1ad65..93935d8c 100644 --- a/spring-web-client-oauth2-reactive-stack/src/main/java/de/rieckpil/blog/GitHubController.java +++ b/spring-web-client-oauth2-reactive-stack/src/main/java/de/rieckpil/blog/GitHubController.java @@ -1,6 +1,9 @@ package de.rieckpil.blog; +import static org.springframework.security.oauth2.client.web.reactive.function.client.ServerOAuth2AuthorizedClientExchangeFilterFunction.oauth2AuthorizedClient; + import com.fasterxml.jackson.databind.JsonNode; +import java.util.List; import org.springframework.core.ParameterizedTypeReference; import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.security.oauth2.client.OAuth2AuthorizedClient; @@ -13,48 +16,40 @@ import org.springframework.web.reactive.function.client.WebClient; import reactor.core.publisher.Flux; -import java.util.List; - -import static org.springframework.security.oauth2.client.web.reactive.function.client.ServerOAuth2AuthorizedClientExchangeFilterFunction.oauth2AuthorizedClient; - @Controller @RequestMapping("/") public class GitHubController { - private static final String GITHUB_API_URL = "https://api.github.com"; - - private WebClient webClient; - - public GitHubController(WebClient webClient) { - this.webClient = webClient; - } - - @GetMapping - public String index(@RegisteredOAuth2AuthorizedClient OAuth2AuthorizedClient authorizedClient, - @AuthenticationPrincipal OAuth2User oauth2User, - Model model) { - - model.addAttribute("repositories", fetchAllRepositories(authorizedClient)); - model.addAttribute("username", oauth2User.getAttributes().get("login")); - - return "index"; - } - - private Flux fetchAllRepositories(OAuth2AuthorizedClient authorizedClient) { - return this.webClient - .get() - .uri(GITHUB_API_URL, uriBuilder -> - uriBuilder - .path("/user/repos") - .queryParam("per_page", 100) - .build() - ) - .attributes(oauth2AuthorizedClient(authorizedClient)) - .retrieve() - .bodyToMono(new ParameterizedTypeReference>() { - }) - .flatMapMany(Flux::fromIterable) - .map(jsonNode -> jsonNode.get("full_name").asText()); - } - + private static final String GITHUB_API_URL = "https://api.github.com"; + + private WebClient webClient; + + public GitHubController(WebClient webClient) { + this.webClient = webClient; + } + + @GetMapping + public String index( + @RegisteredOAuth2AuthorizedClient OAuth2AuthorizedClient authorizedClient, + @AuthenticationPrincipal OAuth2User oauth2User, + Model model) { + + model.addAttribute("repositories", fetchAllRepositories(authorizedClient)); + model.addAttribute("username", oauth2User.getAttributes().get("login")); + + return "index"; + } + + private Flux fetchAllRepositories(OAuth2AuthorizedClient authorizedClient) { + return this.webClient + .get() + .uri( + GITHUB_API_URL, + uriBuilder -> uriBuilder.path("/user/repos").queryParam("per_page", 100).build()) + .attributes(oauth2AuthorizedClient(authorizedClient)) + .retrieve() + .bodyToMono(new ParameterizedTypeReference>() {}) + .flatMapMany(Flux::fromIterable) + .map(jsonNode -> jsonNode.get("full_name").asText()); + } } diff --git a/spring-web-client-oauth2-reactive-stack/src/main/java/de/rieckpil/blog/SecurityConfiguration.java b/spring-web-client-oauth2-reactive-stack/src/main/java/de/rieckpil/blog/SecurityConfiguration.java index d0d6727d..ac32faee 100644 --- a/spring-web-client-oauth2-reactive-stack/src/main/java/de/rieckpil/blog/SecurityConfiguration.java +++ b/spring-web-client-oauth2-reactive-stack/src/main/java/de/rieckpil/blog/SecurityConfiguration.java @@ -2,22 +2,22 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.Customizer; +import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity; import org.springframework.security.config.web.server.ServerHttpSecurity; import org.springframework.security.web.server.SecurityWebFilterChain; -import static org.springframework.security.config.Customizer.withDefaults; - @Configuration +@EnableWebFluxSecurity public class SecurityConfiguration { - @Bean - SecurityWebFilterChain configure(ServerHttpSecurity http) { - return http - .authorizeExchange(exchanges -> - exchanges.anyExchange().authenticated() - ) - .oauth2Login(withDefaults()) - .oauth2Client(withDefaults()) - .build(); - } + @Bean + public SecurityWebFilterChain configure(ServerHttpSecurity http) { + http.authorizeExchange( + authorizeExchangeSpec -> authorizeExchangeSpec.anyExchange().authenticated()) + .oauth2Client(Customizer.withDefaults()) + .oauth2Login(Customizer.withDefaults()); + + return http.build(); + } } diff --git a/spring-web-client-oauth2-reactive-stack/src/main/java/de/rieckpil/blog/SpringWebClientOauth2Application.java b/spring-web-client-oauth2-reactive-stack/src/main/java/de/rieckpil/blog/SpringWebClientOauth2Application.java index 1ec957f1..e17ddb0b 100644 --- a/spring-web-client-oauth2-reactive-stack/src/main/java/de/rieckpil/blog/SpringWebClientOauth2Application.java +++ b/spring-web-client-oauth2-reactive-stack/src/main/java/de/rieckpil/blog/SpringWebClientOauth2Application.java @@ -6,8 +6,7 @@ @SpringBootApplication public class SpringWebClientOauth2Application { - public static void main(String[] args) { - SpringApplication.run(SpringWebClientOauth2Application.class, args); - } - + public static void main(String[] args) { + SpringApplication.run(SpringWebClientOauth2Application.class, args); + } } diff --git a/spring-web-client-oauth2-reactive-stack/src/main/java/de/rieckpil/blog/WebClientConfig.java b/spring-web-client-oauth2-reactive-stack/src/main/java/de/rieckpil/blog/WebClientConfig.java index 0f61adee..19bd4932 100644 --- a/spring-web-client-oauth2-reactive-stack/src/main/java/de/rieckpil/blog/WebClientConfig.java +++ b/spring-web-client-oauth2-reactive-stack/src/main/java/de/rieckpil/blog/WebClientConfig.java @@ -14,31 +14,27 @@ @Configuration public class WebClientConfig { - @Bean - public WebClient webClient(ReactiveOAuth2AuthorizedClientManager authorizedClientManager) { - ServerOAuth2AuthorizedClientExchangeFilterFunction oauth = - new ServerOAuth2AuthorizedClientExchangeFilterFunction(authorizedClientManager); - return WebClient.builder() - .filter(oauth) - .build(); - } - - @Bean - public ReactiveOAuth2AuthorizedClientManager authorizedClientManager( - ReactiveClientRegistrationRepository clientRegistrationRepository, - ServerOAuth2AuthorizedClientRepository authorizedClientRepository) { - - ReactiveOAuth2AuthorizedClientProvider authorizedClientProvider = - ReactiveOAuth2AuthorizedClientProviderBuilder.builder() - .authorizationCode() - .build(); - - DefaultReactiveOAuth2AuthorizedClientManager authorizedClientManager = - new DefaultReactiveOAuth2AuthorizedClientManager( - clientRegistrationRepository, authorizedClientRepository); - - authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider); - - return authorizedClientManager; - } + @Bean + public WebClient webClient(ReactiveOAuth2AuthorizedClientManager authorizedClientManager) { + ServerOAuth2AuthorizedClientExchangeFilterFunction oauth = + new ServerOAuth2AuthorizedClientExchangeFilterFunction(authorizedClientManager); + return WebClient.builder().filter(oauth).build(); + } + + @Bean + public ReactiveOAuth2AuthorizedClientManager authorizedClientManager( + ReactiveClientRegistrationRepository clientRegistrationRepository, + ServerOAuth2AuthorizedClientRepository authorizedClientRepository) { + + ReactiveOAuth2AuthorizedClientProvider authorizedClientProvider = + ReactiveOAuth2AuthorizedClientProviderBuilder.builder().authorizationCode().build(); + + DefaultReactiveOAuth2AuthorizedClientManager authorizedClientManager = + new DefaultReactiveOAuth2AuthorizedClientManager( + clientRegistrationRepository, authorizedClientRepository); + + authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider); + + return authorizedClientManager; + } } diff --git a/spring-web-client-oauth2-reactive-stack/src/test/java/de/rieckpil/blog/SpringWebClientOauth2ApplicationTests.java b/spring-web-client-oauth2-reactive-stack/src/test/java/de/rieckpil/blog/SpringWebClientOauth2ApplicationTests.java index 4658a301..301542be 100644 --- a/spring-web-client-oauth2-reactive-stack/src/test/java/de/rieckpil/blog/SpringWebClientOauth2ApplicationTests.java +++ b/spring-web-client-oauth2-reactive-stack/src/test/java/de/rieckpil/blog/SpringWebClientOauth2ApplicationTests.java @@ -6,8 +6,6 @@ @SpringBootTest class SpringWebClientOauth2ApplicationTests { - @Test - void contextLoads() { - } - + @Test + void contextLoads() {} } diff --git a/spring-web-client-oauth2-servlet-stack/pom.xml b/spring-web-client-oauth2-servlet-stack/pom.xml index 6078a8e5..3558b0af 100644 --- a/spring-web-client-oauth2-servlet-stack/pom.xml +++ b/spring-web-client-oauth2-servlet-stack/pom.xml @@ -2,22 +2,18 @@ 4.0.0 - - org.springframework.boot - spring-boot-starter-parent - 2.2.2.RELEASE - - + de.rieckpil.blog + blog-parent + 0.0.1-SNAPSHOT + ../pom.xml + + spring-web-client-oauth2-servlet-stack 0.0.1-SNAPSHOT spring-web-client-oauth2-servlet-stack - - 11 - - org.springframework.boot diff --git a/spring-web-client-oauth2-servlet-stack/src/main/java/de/rieckpil/blog/GitHubController.java b/spring-web-client-oauth2-servlet-stack/src/main/java/de/rieckpil/blog/GitHubController.java index 8f71c896..d9467e02 100644 --- a/spring-web-client-oauth2-servlet-stack/src/main/java/de/rieckpil/blog/GitHubController.java +++ b/spring-web-client-oauth2-servlet-stack/src/main/java/de/rieckpil/blog/GitHubController.java @@ -1,6 +1,10 @@ package de.rieckpil.blog; +import static org.springframework.security.oauth2.client.web.reactive.function.client.ServerOAuth2AuthorizedClientExchangeFilterFunction.oauth2AuthorizedClient; + import com.fasterxml.jackson.databind.node.ArrayNode; +import java.util.ArrayList; +import java.util.List; import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.security.oauth2.client.OAuth2AuthorizedClient; import org.springframework.security.oauth2.client.annotation.RegisteredOAuth2AuthorizedClient; @@ -11,52 +15,44 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.reactive.function.client.WebClient; -import java.util.ArrayList; -import java.util.List; - -import static org.springframework.security.oauth2.client.web.reactive.function.client.ServerOAuth2AuthorizedClientExchangeFilterFunction.oauth2AuthorizedClient; - @Controller @RequestMapping("/") public class GitHubController { - private static final String GITHUB_API_URL = "https://api.github.com"; - - private WebClient webClient; + private static final String GITHUB_API_URL = "https://api.github.com"; - public GitHubController(WebClient webClient) { - this.webClient = webClient; - } + private WebClient webClient; - @GetMapping - public String index(@RegisteredOAuth2AuthorizedClient OAuth2AuthorizedClient authorizedClient, - @AuthenticationPrincipal OAuth2User oauth2User, - Model model) { + public GitHubController(WebClient webClient) { + this.webClient = webClient; + } - model.addAttribute("repositories", fetchAllRepositories(authorizedClient)); - model.addAttribute("username", oauth2User.getAttributes().get("login")); + @GetMapping + public String index( + @RegisteredOAuth2AuthorizedClient OAuth2AuthorizedClient authorizedClient, + @AuthenticationPrincipal OAuth2User oauth2User, + Model model) { - return "index"; - } + model.addAttribute("repositories", fetchAllRepositories(authorizedClient)); + model.addAttribute("username", oauth2User.getAttributes().get("login")); - private List fetchAllRepositories(OAuth2AuthorizedClient authorizedClient) { - List repositoryNames = new ArrayList<>(); + return "index"; + } - this.webClient - .get() - .uri(GITHUB_API_URL, uriBuilder -> - uriBuilder - .path("/user/repos") - .queryParam("per_page", 100) - .build() - ) - .attributes(oauth2AuthorizedClient(authorizedClient)) - .retrieve() - .bodyToMono(ArrayNode.class) - .block() - .forEach(jsonNode -> repositoryNames.add(jsonNode.get("full_name").asText())); + private List fetchAllRepositories(OAuth2AuthorizedClient authorizedClient) { + List repositoryNames = new ArrayList<>(); - return repositoryNames; - } + this.webClient + .get() + .uri( + GITHUB_API_URL, + uriBuilder -> uriBuilder.path("/user/repos").queryParam("per_page", 100).build()) + .attributes(oauth2AuthorizedClient(authorizedClient)) + .retrieve() + .bodyToMono(ArrayNode.class) + .block() + .forEach(jsonNode -> repositoryNames.add(jsonNode.get("full_name").asText())); + return repositoryNames; + } } diff --git a/spring-web-client-oauth2-servlet-stack/src/main/java/de/rieckpil/blog/SecurityConfiguration.java b/spring-web-client-oauth2-servlet-stack/src/main/java/de/rieckpil/blog/SecurityConfiguration.java index ffb3c25d..1870f6ca 100644 --- a/spring-web-client-oauth2-servlet-stack/src/main/java/de/rieckpil/blog/SecurityConfiguration.java +++ b/spring-web-client-oauth2-servlet-stack/src/main/java/de/rieckpil/blog/SecurityConfiguration.java @@ -1,21 +1,23 @@ package de.rieckpil.blog; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.Customizer; import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.web.SecurityFilterChain; @Configuration -public class SecurityConfiguration extends WebSecurityConfigurerAdapter { +public class SecurityConfiguration { - @Override - protected void configure(HttpSecurity http) throws Exception { - http - .authorizeRequests() - .anyRequest().authenticated() - .and() - .oauth2Client() - .and() - .oauth2Login(); - } + @Bean + public SecurityFilterChain configure(HttpSecurity http) throws Exception { + http.authorizeRequests() + .anyRequest() + .authenticated() + .and() + .oauth2Client(Customizer.withDefaults()) + .oauth2Login(Customizer.withDefaults()); + return http.build(); + } } diff --git a/spring-web-client-oauth2-servlet-stack/src/main/java/de/rieckpil/blog/SpringWebClientOauth2Application.java b/spring-web-client-oauth2-servlet-stack/src/main/java/de/rieckpil/blog/SpringWebClientOauth2Application.java index 1ec957f1..e17ddb0b 100644 --- a/spring-web-client-oauth2-servlet-stack/src/main/java/de/rieckpil/blog/SpringWebClientOauth2Application.java +++ b/spring-web-client-oauth2-servlet-stack/src/main/java/de/rieckpil/blog/SpringWebClientOauth2Application.java @@ -6,8 +6,7 @@ @SpringBootApplication public class SpringWebClientOauth2Application { - public static void main(String[] args) { - SpringApplication.run(SpringWebClientOauth2Application.class, args); - } - + public static void main(String[] args) { + SpringApplication.run(SpringWebClientOauth2Application.class, args); + } } diff --git a/spring-web-client-oauth2-servlet-stack/src/main/java/de/rieckpil/blog/WebClientConfig.java b/spring-web-client-oauth2-servlet-stack/src/main/java/de/rieckpil/blog/WebClientConfig.java index c8a70283..29e4e345 100644 --- a/spring-web-client-oauth2-servlet-stack/src/main/java/de/rieckpil/blog/WebClientConfig.java +++ b/spring-web-client-oauth2-servlet-stack/src/main/java/de/rieckpil/blog/WebClientConfig.java @@ -13,26 +13,25 @@ @Configuration public class WebClientConfig { - @Bean - public WebClient webClient(OAuth2AuthorizedClientManager authorizedClientManager) { - ServletOAuth2AuthorizedClientExchangeFilterFunction oauth = - new ServletOAuth2AuthorizedClientExchangeFilterFunction(authorizedClientManager); - return WebClient.builder() - .filter(oauth) - .build(); - } + @Bean + public WebClient webClient(OAuth2AuthorizedClientManager authorizedClientManager) { + ServletOAuth2AuthorizedClientExchangeFilterFunction oauth = + new ServletOAuth2AuthorizedClientExchangeFilterFunction(authorizedClientManager); + return WebClient.builder().filter(oauth).build(); + } - @Bean - public OAuth2AuthorizedClientManager authorizedClientManager( - ClientRegistrationRepository clientRegistrationRepository, - OAuth2AuthorizedClientRepository authorizedClientRepository) { + @Bean + public OAuth2AuthorizedClientManager authorizedClientManager( + ClientRegistrationRepository clientRegistrationRepository, + OAuth2AuthorizedClientRepository authorizedClientRepository) { - DefaultOAuth2AuthorizedClientManager authorizedClientManager = - new DefaultOAuth2AuthorizedClientManager( - clientRegistrationRepository, authorizedClientRepository); + DefaultOAuth2AuthorizedClientManager authorizedClientManager = + new DefaultOAuth2AuthorizedClientManager( + clientRegistrationRepository, authorizedClientRepository); - authorizedClientManager.setAuthorizedClientProvider(new AuthorizationCodeOAuth2AuthorizedClientProvider()); + authorizedClientManager.setAuthorizedClientProvider( + new AuthorizationCodeOAuth2AuthorizedClientProvider()); - return authorizedClientManager; - } + return authorizedClientManager; + } } diff --git a/spring-web-client-oauth2-servlet-stack/src/test/java/de/rieckpil/blog/SpringWebClientOauth2ApplicationTests.java b/spring-web-client-oauth2-servlet-stack/src/test/java/de/rieckpil/blog/SpringWebClientOauth2ApplicationTests.java index 4658a301..301542be 100644 --- a/spring-web-client-oauth2-servlet-stack/src/test/java/de/rieckpil/blog/SpringWebClientOauth2ApplicationTests.java +++ b/spring-web-client-oauth2-servlet-stack/src/test/java/de/rieckpil/blog/SpringWebClientOauth2ApplicationTests.java @@ -6,8 +6,6 @@ @SpringBootTest class SpringWebClientOauth2ApplicationTests { - @Test - void contextLoads() { - } - + @Test + void contextLoads() {} } diff --git a/spring-web-client-testing-with-mockwebserver/pom.xml b/spring-web-client-testing-with-mockwebserver/pom.xml index 8dbe95a1..385a797f 100644 --- a/spring-web-client-testing-with-mockwebserver/pom.xml +++ b/spring-web-client-testing-with-mockwebserver/pom.xml @@ -3,20 +3,18 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - org.springframework.boot - spring-boot-starter-parent - 2.3.0.RELEASE - + de.rieckpil.blog + blog-parent + 0.0.1-SNAPSHOT + ../pom.xml - de.rieckpil.blog spring-web-client-testing-with-mockwebserver 0.0.1-SNAPSHOT spring-web-client-testing-with-mockwebserver Demo project for Spring Boot - 11 4.7.2 4.7.2 diff --git a/spring-web-client-testing-with-mockwebserver/src/main/java/de/rieckpil/blog/Application.java b/spring-web-client-testing-with-mockwebserver/src/main/java/de/rieckpil/blog/Application.java index ad872b65..478dedf1 100644 --- a/spring-web-client-testing-with-mockwebserver/src/main/java/de/rieckpil/blog/Application.java +++ b/spring-web-client-testing-with-mockwebserver/src/main/java/de/rieckpil/blog/Application.java @@ -6,8 +6,6 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import java.math.BigDecimal; - @SpringBootApplication public class Application implements CommandLineRunner { @@ -19,7 +17,6 @@ public Application(UsersClient usersClient, ObjectMapper objectMapper) { this.objectMapper = objectMapper; } - public static void main(String[] args) { SpringApplication.run(Application.class, args); } @@ -31,10 +28,9 @@ public void run(String... args) throws Exception { ObjectNode objectNode = objectMapper.createObjectNode(); objectNode.put("name", "duke"); objectNode.put("email", "duke@java.io"); - objectNode.set("address", - objectMapper.createObjectNode() - .put("street", "main") - .put("postalCode", "91074")); + objectNode.set( + "address", + objectMapper.createObjectNode().put("street", "main").put("postalCode", "91074")); objectNode.set("hobbies", objectMapper.createArrayNode().add("sports").add("bowling")); System.out.println(usersClient.createNewUser(objectNode)); diff --git a/spring-web-client-testing-with-mockwebserver/src/main/java/de/rieckpil/blog/RetryClient.java b/spring-web-client-testing-with-mockwebserver/src/main/java/de/rieckpil/blog/RetryClient.java index cda37645..70f59d97 100644 --- a/spring-web-client-testing-with-mockwebserver/src/main/java/de/rieckpil/blog/RetryClient.java +++ b/spring-web-client-testing-with-mockwebserver/src/main/java/de/rieckpil/blog/RetryClient.java @@ -3,37 +3,38 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; +import java.time.Duration; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import org.springframework.web.reactive.function.client.WebClient; import reactor.core.publisher.Mono; import reactor.util.retry.Retry; -import java.time.Duration; - @Component public class RetryClient { private final WebClient webClient; private final ObjectMapper objectMapper; - public RetryClient(WebClient.Builder builder, - @Value("${clients.users.url}") String usersBaseUrl, ObjectMapper objectMapper) { + public RetryClient( + WebClient.Builder builder, + @Value("${clients.users.url}") String usersBaseUrl, + ObjectMapper objectMapper) { this.objectMapper = objectMapper; this.webClient = builder.baseUrl(usersBaseUrl).build(); } public JsonNode getData() { - Mono fallback = Mono.just(this.objectMapper.createObjectNode().put("message", "fallback")); + Mono fallback = + Mono.just(this.objectMapper.createObjectNode().put("message", "fallback")); return this.webClient - .get() - .uri("/data") - .retrieve() - .bodyToMono(JsonNode.class) - .retryWhen(Retry.fixedDelay(2, Duration.ofMillis(100))) - .timeout(Duration.ofSeconds(2), - fallback) - .block(); + .get() + .uri("/data") + .retrieve() + .bodyToMono(JsonNode.class) + .retryWhen(Retry.fixedDelay(2, Duration.ofMillis(100))) + .timeout(Duration.ofSeconds(2), fallback) + .block(); } } diff --git a/spring-web-client-testing-with-mockwebserver/src/main/java/de/rieckpil/blog/UsersClient.java b/spring-web-client-testing-with-mockwebserver/src/main/java/de/rieckpil/blog/UsersClient.java index 3dd31602..5b596128 100644 --- a/spring-web-client-testing-with-mockwebserver/src/main/java/de/rieckpil/blog/UsersClient.java +++ b/spring-web-client-testing-with-mockwebserver/src/main/java/de/rieckpil/blog/UsersClient.java @@ -14,28 +14,29 @@ public class UsersClient { private final WebClient webClient; - public UsersClient(WebClient.Builder builder, - @Value("${clients.users.url}") String usersBaseUrl) { + public UsersClient( + WebClient.Builder builder, @Value("${clients.users.url}") String usersBaseUrl) { this.webClient = builder.baseUrl(usersBaseUrl).build(); } public JsonNode getUserById(Long id) { return this.webClient - .get() - .uri("/users/{id}", id) - .retrieve() - .bodyToMono(JsonNode.class) - .block(); + .get() + .uri("/users/{id}", id) + .retrieve() + .bodyToMono(JsonNode.class) + .block(); } public JsonNode createNewUser(JsonNode payload) { - ClientResponse clientResponse = this.webClient - .post() - .uri("/users") - .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) - .bodyValue(payload) - .exchange() - .block(); + ClientResponse clientResponse = + this.webClient + .post() + .uri("/users") + .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) + .bodyValue(payload) + .exchange() + .block(); if (clientResponse.statusCode().equals(HttpStatus.CREATED)) { return clientResponse.bodyToMono(JsonNode.class).block(); diff --git a/spring-web-client-testing-with-mockwebserver/src/test/java/de/rieckpil/blog/RetryClientTest.java b/spring-web-client-testing-with-mockwebserver/src/test/java/de/rieckpil/blog/RetryClientTest.java index cc43761b..d3956c78 100644 --- a/spring-web-client-testing-with-mockwebserver/src/test/java/de/rieckpil/blog/RetryClientTest.java +++ b/spring-web-client-testing-with-mockwebserver/src/test/java/de/rieckpil/blog/RetryClientTest.java @@ -1,18 +1,17 @@ package de.rieckpil.blog; +import static org.junit.jupiter.api.Assertions.assertEquals; + import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.IOException; +import java.util.concurrent.TimeUnit; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.web.reactive.function.client.WebClient; -import java.io.IOException; -import java.util.concurrent.TimeUnit; - -import static org.junit.jupiter.api.Assertions.assertEquals; - class RetryClientTest { private MockWebServer mockWebServer; @@ -22,21 +21,22 @@ class RetryClientTest { public void setup() throws IOException { this.mockWebServer = new MockWebServer(); this.mockWebServer.start(); - this.retryClient = new RetryClient(WebClient.builder(), mockWebServer.url("/").toString(), new ObjectMapper()); + this.retryClient = + new RetryClient(WebClient.builder(), mockWebServer.url("/").toString(), new ObjectMapper()); } @Test public void testRetry() { - MockResponse failureResponse = new MockResponse() - .setResponseCode(500); + MockResponse failureResponse = new MockResponse().setResponseCode(500); mockWebServer.enqueue(failureResponse); mockWebServer.enqueue(failureResponse); - MockResponse mockResponse = new MockResponse() - .addHeader("Content-Type", "application/json; charset=utf-8") - .setBody("{\"id\": 1, \"name\":\"duke\"}") - .throttleBody(16, 5000, TimeUnit.MILLISECONDS); + MockResponse mockResponse = + new MockResponse() + .addHeader("Content-Type", "application/json; charset=utf-8") + .setBody("{\"id\": 1, \"name\":\"duke\"}") + .throttleBody(16, 5000, TimeUnit.MILLISECONDS); mockWebServer.enqueue(mockResponse); @@ -45,5 +45,4 @@ public void testRetry() { System.out.println(result); assertEquals("fallback", result.get("message").asText()); } - } diff --git a/spring-web-client-testing-with-mockwebserver/src/test/java/de/rieckpil/blog/UsersClientTest.java b/spring-web-client-testing-with-mockwebserver/src/test/java/de/rieckpil/blog/UsersClientTest.java index 7567bf88..b10bee3d 100644 --- a/spring-web-client-testing-with-mockwebserver/src/test/java/de/rieckpil/blog/UsersClientTest.java +++ b/spring-web-client-testing-with-mockwebserver/src/test/java/de/rieckpil/blog/UsersClientTest.java @@ -1,7 +1,12 @@ package de.rieckpil.blog; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.IOException; +import java.util.concurrent.TimeUnit; import okhttp3.mockwebserver.Dispatcher; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; @@ -11,12 +16,6 @@ import org.springframework.web.reactive.function.client.WebClient; import org.springframework.web.reactive.function.client.WebClientResponseException; -import java.io.IOException; -import java.util.concurrent.TimeUnit; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; - class UsersClientTest { private MockWebServer mockWebServer; @@ -31,10 +30,11 @@ public void setup() throws IOException { @Test public void testGetUserById() throws InterruptedException { - MockResponse mockResponse = new MockResponse() - .addHeader("Content-Type", "application/json; charset=utf-8") - .setBody("{\"id\": 1, \"name\":\"duke\"}") - .throttleBody(16, 5, TimeUnit.SECONDS); + MockResponse mockResponse = + new MockResponse() + .addHeader("Content-Type", "application/json; charset=utf-8") + .setBody("{\"id\": 1, \"name\":\"duke\"}") + .throttleBody(16, 5, TimeUnit.SECONDS); mockWebServer.enqueue(mockResponse); @@ -49,15 +49,17 @@ public void testGetUserById() throws InterruptedException { @Test public void testCreatingUsers() { - MockResponse mockResponse = new MockResponse() - .addHeader("Content-Type", "application/json; charset=utf-8") - .setBody("{\"id\": 1, \"name\":\"duke\"}") - .throttleBody(16, 5, TimeUnit.SECONDS) - .setResponseCode(201); + MockResponse mockResponse = + new MockResponse() + .addHeader("Content-Type", "application/json; charset=utf-8") + .setBody("{\"id\": 1, \"name\":\"duke\"}") + .throttleBody(16, 5, TimeUnit.SECONDS) + .setResponseCode(201); mockWebServer.enqueue(mockResponse); - JsonNode result = usersClient.createNewUser(new ObjectMapper().createObjectNode().put("name", "duke")); + JsonNode result = + usersClient.createNewUser(new ObjectMapper().createObjectNode().put("name", "duke")); assertEquals(1, result.get("id").asInt()); assertEquals("duke", result.get("name").asText()); @@ -65,37 +67,39 @@ public void testCreatingUsers() { @Test public void testCreatingUsersWithNon201ResponseCode() { - MockResponse mockResponse = new MockResponse() - .setResponseCode(204); + MockResponse mockResponse = new MockResponse().setResponseCode(204); mockWebServer.enqueue(mockResponse); - assertThrows(RuntimeException.class, () -> - usersClient.createNewUser(new ObjectMapper().createObjectNode().put("name", "duke"))); + assertThrows( + RuntimeException.class, + () -> usersClient.createNewUser(new ObjectMapper().createObjectNode().put("name", "duke"))); } @Test public void testMultipleResponseCodes() { - final Dispatcher dispatcher = new Dispatcher() { - @Override - public MockResponse dispatch(RecordedRequest request) { - switch (request.getPath()) { - case "/users/1": - return new MockResponse().setResponseCode(200); - case "/users/2": - return new MockResponse().setResponseCode(500); - case "/users/3": - return new MockResponse().setResponseCode(200).setBody("{\"id\": 1, \"name\":\"duke\"}"); - } - return new MockResponse().setResponseCode(404); - } - }; + final Dispatcher dispatcher = + new Dispatcher() { + @Override + public MockResponse dispatch(RecordedRequest request) { + switch (request.getPath()) { + case "/users/1": + return new MockResponse().setResponseCode(200); + case "/users/2": + return new MockResponse().setResponseCode(500); + case "/users/3": + return new MockResponse() + .setResponseCode(200) + .setBody("{\"id\": 1, \"name\":\"duke\"}"); + } + return new MockResponse().setResponseCode(404); + } + }; mockWebServer.setDispatcher(dispatcher); assertThrows(WebClientResponseException.class, () -> usersClient.getUserById(2L)); assertThrows(WebClientResponseException.class, () -> usersClient.getUserById(4L)); } - } diff --git a/spring-web-mvc-cheat-sheet/pom.xml b/spring-web-mvc-cheat-sheet/pom.xml index e1fee627..f8fd8c2b 100644 --- a/spring-web-mvc-cheat-sheet/pom.xml +++ b/spring-web-mvc-cheat-sheet/pom.xml @@ -2,22 +2,19 @@ 4.0.0 + - org.springframework.boot - spring-boot-starter-parent - 2.2.6.RELEASE - + de.rieckpil.blog + blog-parent + 0.0.1-SNAPSHOT + ../pom.xml - de.rieckpil.blog + spring-web-mvc-cheat-sheet 0.0.1-SNAPSHOT spring-web-mvc-cheat-sheet Spring Web MVC Cheat Sheet - - 11 - - org.springframework.boot @@ -27,6 +24,10 @@ org.springframework.boot spring-boot-starter-web + + org.springframework.boot + spring-boot-starter-validation + org.springframework.boot spring-boot-starter-webflux @@ -46,6 +47,10 @@ + + jakarta.xml.bind + jakarta.xml.bind-api + diff --git a/spring-web-mvc-cheat-sheet/src/main/java/de/rieckpil/blog/Application.java b/spring-web-mvc-cheat-sheet/src/main/java/de/rieckpil/blog/Application.java index bd5e4c56..6511f3c1 100644 --- a/spring-web-mvc-cheat-sheet/src/main/java/de/rieckpil/blog/Application.java +++ b/spring-web-mvc-cheat-sheet/src/main/java/de/rieckpil/blog/Application.java @@ -9,5 +9,4 @@ public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } - } diff --git a/spring-web-mvc-cheat-sheet/src/main/java/de/rieckpil/blog/FileHandlingController.java b/spring-web-mvc-cheat-sheet/src/main/java/de/rieckpil/blog/FileHandlingController.java index 99f7eaed..e60433f8 100644 --- a/spring-web-mvc-cheat-sheet/src/main/java/de/rieckpil/blog/FileHandlingController.java +++ b/spring-web-mvc-cheat-sheet/src/main/java/de/rieckpil/blog/FileHandlingController.java @@ -1,5 +1,6 @@ package de.rieckpil.blog; +import java.io.IOException; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; @@ -7,8 +8,6 @@ import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; -import java.io.IOException; - @RestController @RequestMapping("/files") public class FileHandlingController { @@ -34,6 +33,5 @@ public void upload(@RequestParam("file") MultipartFile multipartFile) throws IOE System.out.println("Size: " + multipartFile.getSize()); byte[] content = multipartFile.getBytes(); - } } diff --git a/spring-web-mvc-cheat-sheet/src/main/java/de/rieckpil/blog/JsonPayloadController.java b/spring-web-mvc-cheat-sheet/src/main/java/de/rieckpil/blog/JsonPayloadController.java index ee2ae366..e159f3cc 100644 --- a/spring-web-mvc-cheat-sheet/src/main/java/de/rieckpil/blog/JsonPayloadController.java +++ b/spring-web-mvc-cheat-sheet/src/main/java/de/rieckpil/blog/JsonPayloadController.java @@ -1,5 +1,8 @@ package de.rieckpil.blog; +import java.time.LocalDateTime; +import java.util.List; +import java.util.Set; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; @@ -7,20 +10,16 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import java.time.LocalDateTime; -import java.util.List; -import java.util.Set; - @RestController @RequestMapping("/json") public class JsonPayloadController { @GetMapping(path = "/orders", produces = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity> getOrders() { - List orders = List.of( - new Order("42L", Set.of("foreign", "books"), 1L, LocalDateTime.now()), - new Order("58B", Set.of("fractile", "computer"), 48L, LocalDateTime.now()) - ); + List orders = + List.of( + new Order("42L", Set.of("foreign", "books"), 1L, LocalDateTime.now()), + new Order("58B", Set.of("fractile", "computer"), 48L, LocalDateTime.now())); return ResponseEntity.status(HttpStatus.I_AM_A_TEAPOT).body(orders); } } diff --git a/spring-web-mvc-cheat-sheet/src/main/java/de/rieckpil/blog/MixMediaTypeController.java b/spring-web-mvc-cheat-sheet/src/main/java/de/rieckpil/blog/MixMediaTypeController.java index e8e93d75..c0e4665e 100644 --- a/spring-web-mvc-cheat-sheet/src/main/java/de/rieckpil/blog/MixMediaTypeController.java +++ b/spring-web-mvc-cheat-sheet/src/main/java/de/rieckpil/blog/MixMediaTypeController.java @@ -1,25 +1,25 @@ package de.rieckpil.blog; +import java.time.LocalDateTime; +import java.util.List; +import java.util.Set; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import java.time.LocalDateTime; -import java.util.List; -import java.util.Set; - @RestController @RequestMapping("/mix") public class MixMediaTypeController { - @GetMapping(path = "/orders", produces = {MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE}) + @GetMapping( + path = "/orders", + produces = {MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE}) public List getOrders() { - List orders = List.of( - new Order("42L", Set.of("foreign", "books"), 1L, LocalDateTime.now()), - new Order("58B", Set.of("fractile", "computer"), 48L, LocalDateTime.now()) - ); + List orders = + List.of( + new Order("42L", Set.of("foreign", "books"), 1L, LocalDateTime.now()), + new Order("58B", Set.of("fractile", "computer"), 48L, LocalDateTime.now())); return orders; } - } diff --git a/spring-web-mvc-cheat-sheet/src/main/java/de/rieckpil/blog/Order.java b/spring-web-mvc-cheat-sheet/src/main/java/de/rieckpil/blog/Order.java index 40a63098..049a5bb9 100644 --- a/spring-web-mvc-cheat-sheet/src/main/java/de/rieckpil/blog/Order.java +++ b/spring-web-mvc-cheat-sheet/src/main/java/de/rieckpil/blog/Order.java @@ -1,6 +1,6 @@ package de.rieckpil.blog; -import javax.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.XmlRootElement; import java.time.LocalDateTime; import java.util.Set; @@ -12,8 +12,7 @@ public class Order { private Long customerId; private LocalDateTime orderAt; - public Order() { - } + public Order() {} public Order(String id, Set tags, Long customerId, LocalDateTime orderAt) { this.id = id; diff --git a/spring-web-mvc-cheat-sheet/src/main/java/de/rieckpil/blog/Payload.java b/spring-web-mvc-cheat-sheet/src/main/java/de/rieckpil/blog/Payload.java index 42b6373b..161638dc 100644 --- a/spring-web-mvc-cheat-sheet/src/main/java/de/rieckpil/blog/Payload.java +++ b/spring-web-mvc-cheat-sheet/src/main/java/de/rieckpil/blog/Payload.java @@ -1,20 +1,17 @@ package de.rieckpil.blog; -import javax.validation.constraints.Email; -import javax.validation.constraints.Future; -import javax.validation.constraints.NotBlank; +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.Future; +import jakarta.validation.constraints.NotBlank; import java.time.LocalDateTime; public class Payload { - @NotBlank - private String message; + @NotBlank private String message; - @Email - private String email; + @Email private String email; - @Future - private LocalDateTime memberSince; + @Future private LocalDateTime memberSince; public String getMessage() { return message; diff --git a/spring-web-mvc-cheat-sheet/src/main/java/de/rieckpil/blog/ValidationController.java b/spring-web-mvc-cheat-sheet/src/main/java/de/rieckpil/blog/ValidationController.java index 7673f34d..42b00179 100644 --- a/spring-web-mvc-cheat-sheet/src/main/java/de/rieckpil/blog/ValidationController.java +++ b/spring-web-mvc-cheat-sheet/src/main/java/de/rieckpil/blog/ValidationController.java @@ -1,15 +1,14 @@ package de.rieckpil.blog; +import jakarta.validation.ConstraintViolationException; +import jakarta.validation.Valid; +import jakarta.validation.constraints.Positive; +import jakarta.validation.constraints.Size; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; -import javax.validation.ConstraintViolationException; -import javax.validation.Valid; -import javax.validation.constraints.Positive; -import javax.validation.constraints.Size; - @Validated @RestController @RequestMapping("/validation") @@ -17,16 +16,16 @@ public class ValidationController { @GetMapping("/{message}") public String validateParameters( - @PathVariable("message") @Size(min = 5, max = 10) String message, - @RequestParam("size") @Positive Long size) { + @PathVariable("message") @Size(min = 5, max = 10) String message, + @RequestParam("size") @Positive Long size) { return "Query parameters where valid"; } -@PostMapping -public String validatePayload(@Valid @RequestBody Payload payload) { - return "Payload is valid"; -} + @PostMapping + public String validatePayload(@Valid @RequestBody Payload payload) { + return "Payload is valid"; + } @ExceptionHandler(ConstraintViolationException.class) @ResponseStatus(HttpStatus.BAD_REQUEST) @@ -34,4 +33,3 @@ ResponseEntity handleConstraintViolationException(ConstraintViolationExc return new ResponseEntity<>("Validation Error: " + e.getMessage(), HttpStatus.BAD_REQUEST); } } - diff --git a/spring-web-mvc-cheat-sheet/src/main/java/de/rieckpil/blog/XmlPayloadController.java b/spring-web-mvc-cheat-sheet/src/main/java/de/rieckpil/blog/XmlPayloadController.java index d025a298..eb8153c3 100644 --- a/spring-web-mvc-cheat-sheet/src/main/java/de/rieckpil/blog/XmlPayloadController.java +++ b/spring-web-mvc-cheat-sheet/src/main/java/de/rieckpil/blog/XmlPayloadController.java @@ -1,24 +1,23 @@ package de.rieckpil.blog; +import java.time.LocalDateTime; +import java.util.List; +import java.util.Set; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import java.time.LocalDateTime; -import java.util.List; -import java.util.Set; - @RestController @RequestMapping("/xml") public class XmlPayloadController { @GetMapping(path = "/orders", produces = MediaType.APPLICATION_XML_VALUE) public List getOrders() { - List orders = List.of( - new Order("42L", Set.of("foreign", "books"), 1L, LocalDateTime.now()), - new Order("58B", Set.of("fractile", "computer"), 48L, LocalDateTime.now()) - ); + List orders = + List.of( + new Order("42L", Set.of("foreign", "books"), 1L, LocalDateTime.now()), + new Order("58B", Set.of("fractile", "computer"), 48L, LocalDateTime.now())); return orders; } } diff --git a/spring-web-mvc-cheat-sheet/src/test/java/de/rieckpil/blog/ApplicationTest.java b/spring-web-mvc-cheat-sheet/src/test/java/de/rieckpil/blog/ApplicationTest.java index 24eea4ab..b6751e0d 100644 --- a/spring-web-mvc-cheat-sheet/src/test/java/de/rieckpil/blog/ApplicationTest.java +++ b/spring-web-mvc-cheat-sheet/src/test/java/de/rieckpil/blog/ApplicationTest.java @@ -7,7 +7,5 @@ class ApplicationTest { @Test - void contextLoads() { - } - + void contextLoads() {} } diff --git a/spring-web-test-client/pom.xml b/spring-web-test-client/pom.xml index f9047733..b9e382f7 100644 --- a/spring-web-test-client/pom.xml +++ b/spring-web-test-client/pom.xml @@ -4,22 +4,17 @@ 4.0.0 - org.springframework.boot - spring-boot-starter-parent - 2.5.0 - + de.rieckpil.blog + blog-parent + 0.0.1-SNAPSHOT + ../pom.xml - de.rieckpil.blog spring-web-test-client 0.0.1-SNAPSHOT spring-web-test-client Test Endpoints using WebTestClient - - 11 - - org.springframework.boot diff --git a/spring-web-test-client/src/main/java/de/rieckpil/blog/Application.java b/spring-web-test-client/src/main/java/de/rieckpil/blog/Application.java index bd5e4c56..6511f3c1 100644 --- a/spring-web-test-client/src/main/java/de/rieckpil/blog/Application.java +++ b/spring-web-test-client/src/main/java/de/rieckpil/blog/Application.java @@ -9,5 +9,4 @@ public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } - } diff --git a/spring-web-test-client/src/main/java/de/rieckpil/blog/User.java b/spring-web-test-client/src/main/java/de/rieckpil/blog/User.java index 040ae8d9..854c8b10 100644 --- a/spring-web-test-client/src/main/java/de/rieckpil/blog/User.java +++ b/spring-web-test-client/src/main/java/de/rieckpil/blog/User.java @@ -1,21 +1,18 @@ package de.rieckpil.blog; -import javax.validation.constraints.NotEmpty; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; import java.util.Objects; import java.util.Set; class User { - @NotNull - private Long id; + @NotNull private Long id; - @NotEmpty - private String name; + @NotEmpty private String name; private Set tags; - public User() { - } + public User() {} public User(Long id, String name, Set tags) { this.name = name; @@ -52,9 +49,9 @@ public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; User user = (User) o; - return Objects.equals(id, user.id) && - Objects.equals(name, user.name) && - Objects.equals(tags, user.tags); + return Objects.equals(id, user.id) + && Objects.equals(name, user.name) + && Objects.equals(tags, user.tags); } @Override diff --git a/spring-web-test-client/src/main/java/de/rieckpil/blog/UserController.java b/spring-web-test-client/src/main/java/de/rieckpil/blog/UserController.java index 5151ea3e..682e262f 100644 --- a/spring-web-test-client/src/main/java/de/rieckpil/blog/UserController.java +++ b/spring-web-test-client/src/main/java/de/rieckpil/blog/UserController.java @@ -1,15 +1,14 @@ package de.rieckpil.blog; +import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; + +import java.util.List; import org.springframework.http.ResponseEntity; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import org.springframework.web.util.UriComponents; import org.springframework.web.util.UriComponentsBuilder; -import java.util.List; - -import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; - @RestController @RequestMapping(value = "/api/users", produces = APPLICATION_JSON_VALUE) public class UserController { @@ -28,18 +27,24 @@ public List getAllUsers() { @GetMapping("/{id}") public User getUserById(@PathVariable("id") Long id) { return userService - .getUserById(id) - .orElseThrow(() -> new UserNotFoundException(String.format("User with id [%s] not found", id))); + .getUserById(id) + .orElseThrow( + () -> new UserNotFoundException(String.format("User with id [%s] not found", id))); } @PostMapping(consumes = APPLICATION_JSON_VALUE) - public ResponseEntity createNewUser(@RequestBody @Validated User user, UriComponentsBuilder uriComponentsBuilder) { - User addedUser = this.userService.addNewUser(user) - .orElseThrow(() -> new UserAlreadyExistsException( - String.format("User with id [%s] is already present", user.getId()))); + public ResponseEntity createNewUser( + @RequestBody @Validated User user, UriComponentsBuilder uriComponentsBuilder) { + User addedUser = + this.userService + .addNewUser(user) + .orElseThrow( + () -> + new UserAlreadyExistsException( + String.format("User with id [%s] is already present", user.getId()))); UriComponents uriComponents = - uriComponentsBuilder.path("/api/users/{id}").buildAndExpand(addedUser.getId()); + uriComponentsBuilder.path("/api/users/{id}").buildAndExpand(addedUser.getId()); return ResponseEntity.created(uriComponents.toUri()).build(); } @@ -49,4 +54,3 @@ public void deleteUser(@PathVariable("id") Long id) { this.userService.deleteUserById(id); } } - diff --git a/spring-web-test-client/src/main/java/de/rieckpil/blog/UserService.java b/spring-web-test-client/src/main/java/de/rieckpil/blog/UserService.java index bf0d8989..cbb2ffdd 100644 --- a/spring-web-test-client/src/main/java/de/rieckpil/blog/UserService.java +++ b/spring-web-test-client/src/main/java/de/rieckpil/blog/UserService.java @@ -1,12 +1,11 @@ package de.rieckpil.blog; -import org.springframework.stereotype.Service; - -import javax.annotation.PostConstruct; +import jakarta.annotation.PostConstruct; import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.Set; +import org.springframework.stereotype.Service; @Service public class UserService { @@ -26,9 +25,7 @@ public List getAllUsers() { } public Optional getUserById(Long id) { - return this.userList.stream() - .filter(user -> user.getId() == id) - .findFirst(); + return this.userList.stream().filter(user -> user.getId() == id).findFirst(); } public Optional addNewUser(User user) { diff --git a/spring-web-test-client/src/test/java/de/rieckpil/blog/ApplicationIT.java b/spring-web-test-client/src/test/java/de/rieckpil/blog/ApplicationIT.java index 5df39031..c8455621 100644 --- a/spring-web-test-client/src/test/java/de/rieckpil/blog/ApplicationIT.java +++ b/spring-web-test-client/src/test/java/de/rieckpil/blog/ApplicationIT.java @@ -6,8 +6,6 @@ @SpringBootTest class ApplicationIT { - @Test - void contextLoads() { - } - + @Test + void contextLoads() {} } diff --git a/spring-web-test-client/src/test/java/de/rieckpil/blog/UserControllerIT.java b/spring-web-test-client/src/test/java/de/rieckpil/blog/UserControllerIT.java index 2d15eede..415e584a 100644 --- a/spring-web-test-client/src/test/java/de/rieckpil/blog/UserControllerIT.java +++ b/spring-web-test-client/src/test/java/de/rieckpil/blog/UserControllerIT.java @@ -1,5 +1,10 @@ package de.rieckpil.blog; +import static org.springframework.http.HttpHeaders.*; +import static org.springframework.http.HttpStatus.*; +import static org.springframework.http.MediaType.*; + +import java.util.Set; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @@ -7,45 +12,42 @@ import org.springframework.test.web.reactive.server.WebTestClient; import reactor.core.publisher.Mono; -import java.util.Set; - -import static org.springframework.http.HttpHeaders.*; -import static org.springframework.http.HttpStatus.*; -import static org.springframework.http.MediaType.*; - @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) class UserControllerIT { - @Autowired - private WebTestClient webTestClient; + @Autowired private WebTestClient webTestClient; @Test void shouldReturnThreeDefaultUsers() { this.webTestClient - .get() - .uri("/api/users") - .header(ACCEPT, APPLICATION_JSON_VALUE) - .exchange() - .expectStatus() - .is2xxSuccessful() - .expectHeader() - .contentType(APPLICATION_JSON) - .expectBody() - .jsonPath("$.length()").isEqualTo(3) - .jsonPath("$[0].id").isEqualTo(1) - .jsonPath("$[0].name").isEqualTo("duke") - .jsonPath("$[0].tags").isNotEmpty(); + .get() + .uri("/api/users") + .header(ACCEPT, APPLICATION_JSON_VALUE) + .exchange() + .expectStatus() + .is2xxSuccessful() + .expectHeader() + .contentType(APPLICATION_JSON) + .expectBody() + .jsonPath("$.length()") + .isEqualTo(3) + .jsonPath("$[0].id") + .isEqualTo(1) + .jsonPath("$[0].name") + .isEqualTo("duke") + .jsonPath("$[0].tags") + .isNotEmpty(); } @Test void shouldNotSupportMediaTypeXML() { this.webTestClient - .get() - .uri("/api/users") - .header(ACCEPT, APPLICATION_XML_VALUE) - .exchange() - .expectStatus() - .isEqualTo(NOT_ACCEPTABLE); + .get() + .uri("/api/users") + .header(ACCEPT, APPLICATION_XML_VALUE) + .exchange() + .expectStatus() + .isEqualTo(NOT_ACCEPTABLE); } @Test @@ -53,43 +55,41 @@ void shouldCreateNewUser() { var newUser = new User(10L, "test", Set.of("testing", "webtestclient")); - var userCreationResponse = this.webTestClient - .post() - .uri("/api/users") - .body(Mono.just(newUser), User.class) - .header(CONTENT_TYPE, APPLICATION_JSON_VALUE) - .header(ACCEPT, APPLICATION_JSON_VALUE) - .exchange() - .expectStatus() - .isEqualTo(CREATED) - .returnResult(Void.class); + var userCreationResponse = + this.webTestClient + .post() + .uri("/api/users") + .body(Mono.just(newUser), User.class) + .header(CONTENT_TYPE, APPLICATION_JSON_VALUE) + .header(ACCEPT, APPLICATION_JSON_VALUE) + .exchange() + .expectStatus() + .isEqualTo(CREATED) + .returnResult(Void.class); var locationUrlOfNewUser = userCreationResponse.getResponseHeaders().get(LOCATION).get(0); this.webTestClient - .get() - .uri(locationUrlOfNewUser) - .header(ACCEPT, APPLICATION_JSON_VALUE) - .exchange() - .expectStatus() - .isEqualTo(OK) - .expectBody(User.class) - .isEqualTo(newUser); + .get() + .uri(locationUrlOfNewUser) + .header(ACCEPT, APPLICATION_JSON_VALUE) + .exchange() + .expectStatus() + .isEqualTo(OK) + .expectBody(User.class) + .isEqualTo(newUser); - this.webTestClient - .delete() - .uri("/api/users/{id}", newUser.getId()) - .exchange(); + this.webTestClient.delete().uri("/api/users/{id}", newUser.getId()).exchange(); } @Test void shouldReturnNotFoundForUnknownUserId() { this.webTestClient - .get() - .uri("/api/users/{id}", 42) - .header(CONTENT_TYPE, APPLICATION_JSON_VALUE) - .exchange() - .expectStatus() - .isEqualTo(NOT_FOUND); + .get() + .uri("/api/users/{id}", 42) + .header(CONTENT_TYPE, APPLICATION_JSON_VALUE) + .exchange() + .expectStatus() + .isEqualTo(NOT_FOUND); } } diff --git a/spring-websocket-integration-tests/src/main/java/de/rieckpil/blog/Application.java b/spring-websocket-integration-tests/src/main/java/de/rieckpil/blog/Application.java index bd5e4c56..6511f3c1 100644 --- a/spring-websocket-integration-tests/src/main/java/de/rieckpil/blog/Application.java +++ b/spring-websocket-integration-tests/src/main/java/de/rieckpil/blog/Application.java @@ -9,5 +9,4 @@ public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } - } diff --git a/spring-websocket-integration-tests/src/main/java/de/rieckpil/blog/Message.java b/spring-websocket-integration-tests/src/main/java/de/rieckpil/blog/Message.java index 9c5ec264..fbd78751 100644 --- a/spring-websocket-integration-tests/src/main/java/de/rieckpil/blog/Message.java +++ b/spring-websocket-integration-tests/src/main/java/de/rieckpil/blog/Message.java @@ -14,8 +14,6 @@ public void setMessage(String message) { @Override public String toString() { - return "Message{" + - "message='" + message + '\'' + - '}'; + return "Message{" + "message='" + message + '\'' + '}'; } } diff --git a/spring-websocket-integration-tests/src/main/java/de/rieckpil/blog/WebSocketConfig.java b/spring-websocket-integration-tests/src/main/java/de/rieckpil/blog/WebSocketConfig.java index 93229169..96baa008 100644 --- a/spring-websocket-integration-tests/src/main/java/de/rieckpil/blog/WebSocketConfig.java +++ b/spring-websocket-integration-tests/src/main/java/de/rieckpil/blog/WebSocketConfig.java @@ -18,7 +18,6 @@ public void configureMessageBroker(MessageBrokerRegistry config) { @Override public void registerStompEndpoints(StompEndpointRegistry registry) { - registry.addEndpoint("/ws-endpoint") - .withSockJS(); + registry.addEndpoint("/ws-endpoint").withSockJS(); } } diff --git a/spring-websocket-integration-tests/src/test/java/de/rieckpil/blog/GreetingControllerTest.java b/spring-websocket-integration-tests/src/test/java/de/rieckpil/blog/GreetingControllerTest.java index cb4025d1..77f76f2c 100644 --- a/spring-websocket-integration-tests/src/test/java/de/rieckpil/blog/GreetingControllerTest.java +++ b/spring-websocket-integration-tests/src/test/java/de/rieckpil/blog/GreetingControllerTest.java @@ -1,5 +1,12 @@ package de.rieckpil.blog; +import static java.util.concurrent.TimeUnit.SECONDS; +import static org.awaitility.Awaitility.await; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.lang.reflect.Type; +import java.util.List; +import java.util.concurrent.*; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; @@ -15,26 +22,18 @@ import org.springframework.web.socket.sockjs.client.SockJsClient; import org.springframework.web.socket.sockjs.client.WebSocketTransport; -import java.lang.reflect.Type; -import java.util.List; -import java.util.concurrent.*; - -import static java.util.concurrent.TimeUnit.SECONDS; -import static org.awaitility.Awaitility.await; -import static org.junit.jupiter.api.Assertions.assertEquals; - @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) class GreetingControllerTest { - @LocalServerPort - private Integer port; + @LocalServerPort private Integer port; private WebSocketStompClient webSocketStompClient; @BeforeEach void setup() { - this.webSocketStompClient = new WebSocketStompClient(new SockJsClient( - List.of(new WebSocketTransport(new StandardWebSocketClient())))); + this.webSocketStompClient = + new WebSocketStompClient( + new SockJsClient(List.of(new WebSocketTransport(new StandardWebSocketClient())))); } @Test @@ -44,29 +43,31 @@ void verifyGreetingIsReceived() throws Exception { webSocketStompClient.setMessageConverter(new StringMessageConverter()); - StompSession session = webSocketStompClient - .connect(getWsPath(), new StompSessionHandlerAdapter() { - }) - .get(1, SECONDS); + StompSession session = + webSocketStompClient + .connect(getWsPath(), new StompSessionHandlerAdapter() {}) + .get(1, SECONDS); - session.subscribe("/topic/greetings", new StompFrameHandler() { + session.subscribe( + "/topic/greetings", + new StompFrameHandler() { - @Override - public Type getPayloadType(StompHeaders headers) { - return String.class; - } + @Override + public Type getPayloadType(StompHeaders headers) { + return String.class; + } - @Override - public void handleFrame(StompHeaders headers, Object payload) { - blockingQueue.add((String) payload); - } - }); + @Override + public void handleFrame(StompHeaders headers, Object payload) { + blockingQueue.add((String) payload); + } + }); session.send("/app/welcome", "Mike"); await() - .atMost(1, SECONDS) - .untilAsserted(() -> assertEquals("Hello, Mike!", blockingQueue.poll())); + .atMost(1, SECONDS) + .untilAsserted(() -> assertEquals("Hello, Mike!", blockingQueue.poll())); } @Test @@ -75,31 +76,30 @@ void verifyWelcomeMessageIsSent() throws Exception { webSocketStompClient.setMessageConverter(new MappingJackson2MessageConverter()); - StompSession session = webSocketStompClient - .connect(getWsPath(), new StompSessionHandlerAdapter() { - }) - .get(1, SECONDS); + StompSession session = + webSocketStompClient + .connect(getWsPath(), new StompSessionHandlerAdapter() {}) + .get(1, SECONDS); - session.subscribe("/app/chat", new StompFrameHandler() { + session.subscribe( + "/app/chat", + new StompFrameHandler() { - @Override - public Type getPayloadType(StompHeaders headers) { - return Message.class; - } + @Override + public Type getPayloadType(StompHeaders headers) { + return Message.class; + } - @Override - public void handleFrame(StompHeaders headers, Object payload) { - latch.countDown(); - } - }); + @Override + public void handleFrame(StompHeaders headers, Object payload) { + latch.countDown(); + } + }); - await() - .atMost(1, SECONDS) - .untilAsserted(() -> assertEquals(0, latch.getCount())); + await().atMost(1, SECONDS).untilAsserted(() -> assertEquals(0, latch.getCount())); } private String getWsPath() { return String.format("ws://localhost:%d/ws-endpoint", port); } } - diff --git a/testcontainers-reuse-existing-containers/.java-version b/testcontainers-reuse-existing-containers/.java-version deleted file mode 100644 index 2dbc24b3..00000000 --- a/testcontainers-reuse-existing-containers/.java-version +++ /dev/null @@ -1 +0,0 @@ -11.0 diff --git a/testcontainers-reuse-existing-containers/pom.xml b/testcontainers-reuse-existing-containers/pom.xml index 98c13e0a..d1c553be 100644 --- a/testcontainers-reuse-existing-containers/pom.xml +++ b/testcontainers-reuse-existing-containers/pom.xml @@ -2,24 +2,19 @@ 4.0.0 + - org.springframework.boot - spring-boot-starter-parent - 2.6.0 - + de.rieckpil.blog + blog-parent + 0.0.1-SNAPSHOT + ../pom.xml - de.rieckpil.blog testcontainers-reuse-existing-containers 0.0.1-SNAPSHOT testcontainers-reuse-existing-containers Reuse existing Containers with Testcontainers - - 11 - 1.16.2 - - org.springframework.boot @@ -53,25 +48,7 @@ - - - org.springframework.boot - spring-boot-maven-plugin - - - org.apache.maven.plugins - maven-failsafe-plugin - 3.0.0-M5 - - - - integration-test - verify - - - - - + diff --git a/testcontainers-reuse-existing-containers/src/main/java/de/rieckpil/blog/Application.java b/testcontainers-reuse-existing-containers/src/main/java/de/rieckpil/blog/Application.java index bd5e4c56..6511f3c1 100644 --- a/testcontainers-reuse-existing-containers/src/main/java/de/rieckpil/blog/Application.java +++ b/testcontainers-reuse-existing-containers/src/main/java/de/rieckpil/blog/Application.java @@ -9,5 +9,4 @@ public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } - } diff --git a/testcontainers-reuse-existing-containers/src/main/java/de/rieckpil/blog/Todo.java b/testcontainers-reuse-existing-containers/src/main/java/de/rieckpil/blog/Todo.java index 1f08d3dd..7c40f4a5 100644 --- a/testcontainers-reuse-existing-containers/src/main/java/de/rieckpil/blog/Todo.java +++ b/testcontainers-reuse-existing-containers/src/main/java/de/rieckpil/blog/Todo.java @@ -1,6 +1,6 @@ package de.rieckpil.blog; -import javax.persistence.*; +import jakarta.persistence.*; import java.time.LocalDateTime; @Entity @@ -17,8 +17,7 @@ public class Todo { @Column(nullable = false) private LocalDateTime dueDate; - public Todo() { - } + public Todo() {} public Todo(String title, LocalDateTime dueDate) { this.id = null; diff --git a/testcontainers-reuse-existing-containers/src/main/java/de/rieckpil/blog/TodoController.java b/testcontainers-reuse-existing-containers/src/main/java/de/rieckpil/blog/TodoController.java index b26e1a25..865b0ef2 100644 --- a/testcontainers-reuse-existing-containers/src/main/java/de/rieckpil/blog/TodoController.java +++ b/testcontainers-reuse-existing-containers/src/main/java/de/rieckpil/blog/TodoController.java @@ -1,11 +1,10 @@ package de.rieckpil.blog; +import java.util.List; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import java.util.List; - @RestController @RequestMapping("/todos") public class TodoController { diff --git a/testcontainers-reuse-existing-containers/src/main/java/de/rieckpil/blog/TodoRepository.java b/testcontainers-reuse-existing-containers/src/main/java/de/rieckpil/blog/TodoRepository.java index 8c13c2c3..407bbf80 100644 --- a/testcontainers-reuse-existing-containers/src/main/java/de/rieckpil/blog/TodoRepository.java +++ b/testcontainers-reuse-existing-containers/src/main/java/de/rieckpil/blog/TodoRepository.java @@ -2,5 +2,4 @@ import org.springframework.data.jpa.repository.JpaRepository; -public interface TodoRepository extends JpaRepository { -} +public interface TodoRepository extends JpaRepository {} diff --git a/testcontainers-reuse-existing-containers/src/test/java/de/rieckpil/blog/ApplicationIT.java b/testcontainers-reuse-existing-containers/src/test/java/de/rieckpil/blog/ApplicationIT.java index 5687f56d..de307669 100644 --- a/testcontainers-reuse-existing-containers/src/test/java/de/rieckpil/blog/ApplicationIT.java +++ b/testcontainers-reuse-existing-containers/src/test/java/de/rieckpil/blog/ApplicationIT.java @@ -1,23 +1,16 @@ package de.rieckpil.blog; +import static org.junit.jupiter.api.Assertions.assertEquals; + import com.fasterxml.jackson.databind.JsonNode; -import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; 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.http.ResponseEntity; -import org.springframework.test.context.DynamicPropertyRegistry; -import org.springframework.test.context.DynamicPropertySource; -import org.testcontainers.containers.PostgreSQLContainer; - -import static org.junit.jupiter.api.Assertions.assertEquals; -class ApplicationIT extends BaseIT{ +class ApplicationIT extends BaseIT { - @Autowired - private TestRestTemplate testRestTemplate; + @Autowired private TestRestTemplate testRestTemplate; @Test void contextLoads() { diff --git a/testcontainers-reuse-existing-containers/src/test/java/de/rieckpil/blog/BaseIT.java b/testcontainers-reuse-existing-containers/src/test/java/de/rieckpil/blog/BaseIT.java index 560902ab..14d4a5eb 100644 --- a/testcontainers-reuse-existing-containers/src/test/java/de/rieckpil/blog/BaseIT.java +++ b/testcontainers-reuse-existing-containers/src/test/java/de/rieckpil/blog/BaseIT.java @@ -1,24 +1,25 @@ package de.rieckpil.blog; +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; + import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.DynamicPropertyRegistry; import org.springframework.test.context.DynamicPropertySource; import org.testcontainers.containers.PostgreSQLContainer; import org.testcontainers.utility.DockerImageName; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - @SpringBootTest(webEnvironment = RANDOM_PORT) public abstract class BaseIT { static final PostgreSQLContainer postgreSQLContainer; static { - postgreSQLContainer = new PostgreSQLContainer<>(DockerImageName.parse("postgres:13")) - .withDatabaseName("test") - .withUsername("duke") - .withPassword("s3cret") - .withReuse(true); + postgreSQLContainer = + new PostgreSQLContainer<>(DockerImageName.parse("postgres:13")) + .withDatabaseName("test") + .withUsername("duke") + .withPassword("s3cret") + .withReuse(true); postgreSQLContainer.start(); } diff --git a/testcontainers-reuse-existing-containers/src/test/java/de/rieckpil/blog/SecondApplicationIT.java b/testcontainers-reuse-existing-containers/src/test/java/de/rieckpil/blog/SecondApplicationIT.java index 1f36e107..2193b80d 100644 --- a/testcontainers-reuse-existing-containers/src/test/java/de/rieckpil/blog/SecondApplicationIT.java +++ b/testcontainers-reuse-existing-containers/src/test/java/de/rieckpil/blog/SecondApplicationIT.java @@ -1,32 +1,25 @@ package de.rieckpil.blog; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + import com.fasterxml.jackson.databind.node.ArrayNode; +import java.time.LocalDateTime; +import java.util.List; import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; 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.http.ResponseEntity; -import org.springframework.test.context.DynamicPropertyRegistry; -import org.springframework.test.context.DynamicPropertySource; -import org.testcontainers.containers.PostgreSQLContainer; - -import java.time.LocalDateTime; -import java.util.List; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) -class SecondApplicationIT extends BaseIT{ +class SecondApplicationIT extends BaseIT { - @Autowired - private TestRestTemplate testRestTemplate; + @Autowired private TestRestTemplate testRestTemplate; - @Autowired - private TodoRepository todoRepository; + @Autowired private TodoRepository todoRepository; @AfterEach public void cleanup() { @@ -35,10 +28,13 @@ public void cleanup() { @Test void contextLoads() { - this.todoRepository.saveAll(List.of(new Todo("Write blog post", LocalDateTime.now().plusDays(2)), - new Todo("Clean apartment", LocalDateTime.now().plusDays(4)))); + this.todoRepository.saveAll( + List.of( + new Todo("Write blog post", LocalDateTime.now().plusDays(2)), + new Todo("Clean apartment", LocalDateTime.now().plusDays(4)))); - ResponseEntity result = this.testRestTemplate.getForEntity("/todos", ArrayNode.class); + ResponseEntity result = + this.testRestTemplate.getForEntity("/todos", ArrayNode.class); assertEquals(200, result.getStatusCodeValue()); assertTrue(result.getBody().isArray()); assertEquals(2, result.getBody().size()); diff --git a/testcontainers-reuse-existing-containers/src/test/java/de/rieckpil/blog/ThirdApplicationIT.java b/testcontainers-reuse-existing-containers/src/test/java/de/rieckpil/blog/ThirdApplicationIT.java index ac70498e..c5b408ee 100644 --- a/testcontainers-reuse-existing-containers/src/test/java/de/rieckpil/blog/ThirdApplicationIT.java +++ b/testcontainers-reuse-existing-containers/src/test/java/de/rieckpil/blog/ThirdApplicationIT.java @@ -1,9 +1,11 @@ package de.rieckpil.blog; -import java.time.LocalDateTime; -import java.util.List; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; import com.fasterxml.jackson.databind.node.ArrayNode; +import java.time.LocalDateTime; +import java.util.List; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; @@ -16,23 +18,19 @@ import org.springframework.test.context.DynamicPropertySource; import org.testcontainers.containers.PostgreSQLContainer; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) class ThirdApplicationIT { - @Autowired - private TestRestTemplate testRestTemplate; + @Autowired private TestRestTemplate testRestTemplate; - @Autowired - private TodoRepository todoRepository; + @Autowired private TodoRepository todoRepository; - static PostgreSQLContainer postgreSQLContainer = new PostgreSQLContainer<>("postgres:10-alpine") - .withDatabaseName("test") - .withUsername("duke") - .withPassword("s3cret") - .withReuse(true); + static PostgreSQLContainer postgreSQLContainer = + new PostgreSQLContainer<>("postgres:10-alpine") + .withDatabaseName("test") + .withUsername("duke") + .withPassword("s3cret") + .withReuse(true); @DynamicPropertySource static void datasourceConfig(DynamicPropertyRegistry registry) { @@ -53,10 +51,13 @@ void cleanup() { @Test void contextLoads() { - this.todoRepository.saveAll(List.of(new Todo("Write blog post", LocalDateTime.now().plusDays(2)), - new Todo("Clean apartment", LocalDateTime.now().plusDays(4)))); + this.todoRepository.saveAll( + List.of( + new Todo("Write blog post", LocalDateTime.now().plusDays(2)), + new Todo("Clean apartment", LocalDateTime.now().plusDays(4)))); - ResponseEntity result = this.testRestTemplate.getForEntity("/todos", ArrayNode.class); + ResponseEntity result = + this.testRestTemplate.getForEntity("/todos", ArrayNode.class); assertEquals(200, result.getStatusCodeValue()); assertTrue(result.getBody().isArray()); assertEquals(2, result.getBody().size()); diff --git a/testing-json-serialization-spring/pom.xml b/testing-json-serialization-spring/pom.xml index 484cc327..ee66c329 100644 --- a/testing-json-serialization-spring/pom.xml +++ b/testing-json-serialization-spring/pom.xml @@ -2,29 +2,24 @@ 4.0.0 + - org.springframework.boot - spring-boot-starter-parent - 2.4.5 - + de.rieckpil.blog + blog-parent + 0.0.1-SNAPSHOT + ../pom.xml - de.rieckpil.blog testing-json-serialization-spring 0.0.1-SNAPSHOT testing-json-serialization-spring Testing JSON serialization with Spring Boot - - 11 - - org.springframework.boot spring-boot-starter-web - org.springframework.boot spring-boot-starter-test diff --git a/testing-json-serialization-spring/src/main/java/de/rieckpil/blog/CarDetailsJsonSerializer.java b/testing-json-serialization-spring/src/main/java/de/rieckpil/blog/CarDetailsJsonSerializer.java index dc817910..ea08e3c6 100644 --- a/testing-json-serialization-spring/src/main/java/de/rieckpil/blog/CarDetailsJsonSerializer.java +++ b/testing-json-serialization-spring/src/main/java/de/rieckpil/blog/CarDetailsJsonSerializer.java @@ -3,18 +3,19 @@ import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.SerializerProvider; -import org.springframework.boot.jackson.JsonComponent; - import java.io.IOException; +import org.springframework.boot.jackson.JsonComponent; @JsonComponent public class CarDetailsJsonSerializer extends JsonSerializer { @Override - public void serialize(CarDetails value, JsonGenerator jsonGenerator, SerializerProvider serializers) throws IOException { + public void serialize( + CarDetails value, JsonGenerator jsonGenerator, SerializerProvider serializers) + throws IOException { jsonGenerator.writeStartObject(); jsonGenerator.writeStringField( - "type", value.getManufacturer() + "|" + value.getType() + "|" + value.getColor()); + "type", value.getManufacturer() + "|" + value.getType() + "|" + value.getColor()); jsonGenerator.writeEndObject(); } } diff --git a/testing-json-serialization-spring/src/main/java/de/rieckpil/blog/TestingJsonSerializationSpringApplication.java b/testing-json-serialization-spring/src/main/java/de/rieckpil/blog/TestingJsonSerializationSpringApplication.java index 4a2c4540..3409f4d0 100644 --- a/testing-json-serialization-spring/src/main/java/de/rieckpil/blog/TestingJsonSerializationSpringApplication.java +++ b/testing-json-serialization-spring/src/main/java/de/rieckpil/blog/TestingJsonSerializationSpringApplication.java @@ -6,8 +6,7 @@ @SpringBootApplication public class TestingJsonSerializationSpringApplication { - public static void main(String[] args) { - SpringApplication.run(TestingJsonSerializationSpringApplication.class, args); - } - + public static void main(String[] args) { + SpringApplication.run(TestingJsonSerializationSpringApplication.class, args); + } } diff --git a/testing-json-serialization-spring/src/main/java/de/rieckpil/blog/UserDetails.java b/testing-json-serialization-spring/src/main/java/de/rieckpil/blog/UserDetails.java index 331a8b91..f557368f 100644 --- a/testing-json-serialization-spring/src/main/java/de/rieckpil/blog/UserDetails.java +++ b/testing-json-serialization-spring/src/main/java/de/rieckpil/blog/UserDetails.java @@ -4,7 +4,6 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.PropertyNamingStrategy; import com.fasterxml.jackson.databind.annotation.JsonNaming; - import java.time.LocalDate; @JsonNaming(PropertyNamingStrategy.LowerCaseStrategy.class) @@ -20,7 +19,8 @@ public class UserDetails { @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) private boolean enabled; - public UserDetails(Long id, String firstName, String lastName, LocalDate dateOfBirth, boolean enabled) { + public UserDetails( + Long id, String firstName, String lastName, LocalDate dateOfBirth, boolean enabled) { this.id = id; this.firstName = firstName; this.lastName = lastName; @@ -67,5 +67,4 @@ public boolean isEnabled() { public void setEnabled(boolean enabled) { this.enabled = enabled; } - } diff --git a/testing-json-serialization-spring/src/test/java/de/rieckpil/blog/CarDetailsJsonTest.java b/testing-json-serialization-spring/src/test/java/de/rieckpil/blog/CarDetailsJsonTest.java index 01f7adfd..4dd970b2 100644 --- a/testing-json-serialization-spring/src/test/java/de/rieckpil/blog/CarDetailsJsonTest.java +++ b/testing-json-serialization-spring/src/test/java/de/rieckpil/blog/CarDetailsJsonTest.java @@ -1,18 +1,17 @@ package de.rieckpil.blog; +import static org.assertj.core.api.Assertions.assertThat; + import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.json.JsonTest; import org.springframework.boot.test.json.JacksonTester; import org.springframework.boot.test.json.JsonContent; -import static org.assertj.core.api.Assertions.assertThat; - @JsonTest class CarDetailsJsonTest { - @Autowired - private JacksonTester json; + @Autowired private JacksonTester json; @Test public void testSerialize() throws Exception { diff --git a/testing-json-serialization-spring/src/test/java/de/rieckpil/blog/UserDetailsJsonTest.java b/testing-json-serialization-spring/src/test/java/de/rieckpil/blog/UserDetailsJsonTest.java index 3a271592..bc9f7e46 100644 --- a/testing-json-serialization-spring/src/test/java/de/rieckpil/blog/UserDetailsJsonTest.java +++ b/testing-json-serialization-spring/src/test/java/de/rieckpil/blog/UserDetailsJsonTest.java @@ -1,49 +1,46 @@ package de.rieckpil.blog; +import static org.assertj.core.api.Assertions.assertThat; + +import java.time.LocalDate; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.json.JsonTest; import org.springframework.boot.test.json.JacksonTester; import org.springframework.boot.test.json.JsonContent; -import java.time.LocalDate; - -import static org.assertj.core.api.Assertions.assertThat; - @JsonTest class UserDetailsJsonTest { - @Autowired - private JacksonTester json; + @Autowired private JacksonTester json; -@Test -public void testSerialize() throws Exception { + @Test + public void testSerialize() throws Exception { - UserDetails userDetails = new UserDetails(1L, "Duke", "Java", - LocalDate.of(1995, 1, 1), true); + UserDetails userDetails = new UserDetails(1L, "Duke", "Java", LocalDate.of(1995, 1, 1), true); - JsonContent result = this.json.write(userDetails); + JsonContent result = this.json.write(userDetails); - assertThat(result).hasJsonPathStringValue("$.firstname"); - assertThat(result).extractingJsonPathStringValue("$.firstname").isEqualTo("Duke"); - assertThat(result).extractingJsonPathStringValue("$.lastname").isEqualTo("Java"); - assertThat(result).extractingJsonPathStringValue("$.dateofbirth").isEqualTo("01.01.1995"); - assertThat(result).doesNotHaveJsonPath("$.enabled"); -} + assertThat(result).hasJsonPathStringValue("$.firstname"); + assertThat(result).extractingJsonPathStringValue("$.firstname").isEqualTo("Duke"); + assertThat(result).extractingJsonPathStringValue("$.lastname").isEqualTo("Java"); + assertThat(result).extractingJsonPathStringValue("$.dateofbirth").isEqualTo("01.01.1995"); + assertThat(result).doesNotHaveJsonPath("$.enabled"); + } -@Test -public void testDeserialize() throws Exception { + @Test + public void testDeserialize() throws Exception { - String jsonContent = "{\"firstname\":\"Mike\", \"lastname\": \"Meyer\", \"dateofbirth\":\"15.05.1990\"," + - " \"id\": 42, \"enabled\": true}"; + String jsonContent = + "{\"firstname\":\"Mike\", \"lastname\": \"Meyer\", \"dateofbirth\":\"15.05.1990\"," + + " \"id\": 42, \"enabled\": true}"; - UserDetails result = this.json.parse(jsonContent).getObject(); - - assertThat(result.getFirstName()).isEqualTo("Mike"); - assertThat(result.getLastName()).isEqualTo("Meyer"); - assertThat(result.getDateOfBirth()).isEqualTo(LocalDate.of(1990, 05, 15)); - assertThat(result.getId()).isEqualTo(42L); - assertThat(result.isEnabled()).isEqualTo(true); -} + UserDetails result = this.json.parse(jsonContent).getObject(); + assertThat(result.getFirstName()).isEqualTo("Mike"); + assertThat(result.getLastName()).isEqualTo("Meyer"); + assertThat(result.getDateOfBirth()).isEqualTo(LocalDate.of(1990, 05, 15)); + assertThat(result.getId()).isEqualTo(42L); + assertThat(result.isEnabled()).isEqualTo(true); + } } diff --git a/testing-spring-boot-applications-with-mockmvc/pom.xml b/testing-spring-boot-applications-with-mockmvc/pom.xml index 8c89b10a..3da2c208 100644 --- a/testing-spring-boot-applications-with-mockmvc/pom.xml +++ b/testing-spring-boot-applications-with-mockmvc/pom.xml @@ -2,22 +2,19 @@ 4.0.0 + - org.springframework.boot - spring-boot-starter-parent - 2.3.4.RELEASE - + de.rieckpil.blog + blog-parent + 0.0.1-SNAPSHOT + ../pom.xml - de.rieckpil.blog + testing-spring-boot-applications-with-mockmvc 0.0.1-SNAPSHOT testing-spring-boot-applications-with-mockmvc Testing Spring Boot Applications with MockMvc - - 11 - - org.springframework.boot @@ -40,12 +37,6 @@ org.springframework.boot spring-boot-starter-test test - - - org.junit.vintage - junit-vintage-engine - - org.springframework.security diff --git a/testing-spring-boot-applications-with-mockmvc/src/main/java/de/rieckpil/blog/Application.java b/testing-spring-boot-applications-with-mockmvc/src/main/java/de/rieckpil/blog/Application.java index bd5e4c56..6511f3c1 100644 --- a/testing-spring-boot-applications-with-mockmvc/src/main/java/de/rieckpil/blog/Application.java +++ b/testing-spring-boot-applications-with-mockmvc/src/main/java/de/rieckpil/blog/Application.java @@ -9,5 +9,4 @@ public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } - } diff --git a/testing-spring-boot-applications-with-mockmvc/src/main/java/de/rieckpil/blog/SecurityConfig.java b/testing-spring-boot-applications-with-mockmvc/src/main/java/de/rieckpil/blog/SecurityConfig.java index cc704b2f..850497f1 100644 --- a/testing-spring-boot-applications-with-mockmvc/src/main/java/de/rieckpil/blog/SecurityConfig.java +++ b/testing-spring-boot-applications-with-mockmvc/src/main/java/de/rieckpil/blog/SecurityConfig.java @@ -1,22 +1,30 @@ package de.rieckpil.blog; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpMethod; +import org.springframework.security.config.Customizer; import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.web.SecurityFilterChain; @Configuration -public class SecurityConfig extends WebSecurityConfigurerAdapter { +public class SecurityConfig { - @Override - protected void configure(HttpSecurity http) throws Exception { - http - .authorizeRequests(authorize -> authorize - .mvcMatchers(HttpMethod.GET, "/dashboard").permitAll() - .mvcMatchers(HttpMethod.GET, "/api/tasks/**").authenticated() - .mvcMatchers("/api/users/**").permitAll() - .mvcMatchers("/**").authenticated() - ) - .httpBasic(); + @Bean + public SecurityFilterChain configure(HttpSecurity http) throws Exception { + http.authorizeRequests( + authorize -> + authorize + .requestMatchers(HttpMethod.GET, "/dashboard") + .permitAll() + .requestMatchers(HttpMethod.GET, "/api/tasks/**") + .authenticated() + .requestMatchers("/api/users/**") + .permitAll() + .requestMatchers("/**") + .authenticated()) + .httpBasic(Customizer.withDefaults()); + + return http.build(); } } diff --git a/testing-spring-boot-applications-with-mockmvc/src/main/java/de/rieckpil/blog/dashboard/DashboardService.java b/testing-spring-boot-applications-with-mockmvc/src/main/java/de/rieckpil/blog/dashboard/DashboardService.java index 89574e86..5468c94b 100644 --- a/testing-spring-boot-applications-with-mockmvc/src/main/java/de/rieckpil/blog/dashboard/DashboardService.java +++ b/testing-spring-boot-applications-with-mockmvc/src/main/java/de/rieckpil/blog/dashboard/DashboardService.java @@ -5,6 +5,6 @@ @Service public class DashboardService { public Integer[] getAnalyticsGraphData() { - return new Integer[]{1, 2, 3, 4, 5, 6}; + return new Integer[] {1, 2, 3, 4, 5, 6}; } } diff --git a/testing-spring-boot-applications-with-mockmvc/src/main/java/de/rieckpil/blog/task/TaskController.java b/testing-spring-boot-applications-with-mockmvc/src/main/java/de/rieckpil/blog/task/TaskController.java index 4b223e2c..9b0cfc35 100644 --- a/testing-spring-boot-applications-with-mockmvc/src/main/java/de/rieckpil/blog/task/TaskController.java +++ b/testing-spring-boot-applications-with-mockmvc/src/main/java/de/rieckpil/blog/task/TaskController.java @@ -1,12 +1,11 @@ package de.rieckpil.blog.task; import com.fasterxml.jackson.databind.JsonNode; +import jakarta.annotation.security.RolesAllowed; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import org.springframework.web.util.UriComponentsBuilder; -import javax.annotation.security.RolesAllowed; - @RestController @RequestMapping("/api/tasks") public class TaskController { @@ -18,13 +17,13 @@ public TaskController(TaskService taskService) { } @PostMapping - public ResponseEntity createNewTask(@RequestBody JsonNode payload, UriComponentsBuilder uriComponentsBuilder) { + public ResponseEntity createNewTask( + @RequestBody JsonNode payload, UriComponentsBuilder uriComponentsBuilder) { Long taskId = this.taskService.createTask(payload.get("taskTitle").asText()); - return ResponseEntity - .created(uriComponentsBuilder.path("/api/tasks/{taskId}").build(taskId)) - .build(); + return ResponseEntity.created(uriComponentsBuilder.path("/api/tasks/{taskId}").build(taskId)) + .build(); } @DeleteMapping diff --git a/testing-spring-boot-applications-with-mockmvc/src/main/java/de/rieckpil/blog/task/TaskService.java b/testing-spring-boot-applications-with-mockmvc/src/main/java/de/rieckpil/blog/task/TaskService.java index 3e514a75..d0bf3e86 100644 --- a/testing-spring-boot-applications-with-mockmvc/src/main/java/de/rieckpil/blog/task/TaskService.java +++ b/testing-spring-boot-applications-with-mockmvc/src/main/java/de/rieckpil/blog/task/TaskService.java @@ -1,8 +1,7 @@ package de.rieckpil.blog.task; -import org.springframework.stereotype.Service; - import java.util.concurrent.ThreadLocalRandom; +import org.springframework.stereotype.Service; @Service public class TaskService { diff --git a/testing-spring-boot-applications-with-mockmvc/src/main/java/de/rieckpil/blog/user/User.java b/testing-spring-boot-applications-with-mockmvc/src/main/java/de/rieckpil/blog/user/User.java index 6169070c..48054caa 100644 --- a/testing-spring-boot-applications-with-mockmvc/src/main/java/de/rieckpil/blog/user/User.java +++ b/testing-spring-boot-applications-with-mockmvc/src/main/java/de/rieckpil/blog/user/User.java @@ -1,18 +1,15 @@ package de.rieckpil.blog.user; -import javax.validation.constraints.Email; -import javax.validation.constraints.NotEmpty; +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.NotEmpty; public class User { - @NotEmpty - private String username; + @NotEmpty private String username; - @Email - private String email; + @Email private String email; - public User() { - } + public User() {} public User(String username, String email) { this.username = username; diff --git a/testing-spring-boot-applications-with-mockmvc/src/main/java/de/rieckpil/blog/user/UserController.java b/testing-spring-boot-applications-with-mockmvc/src/main/java/de/rieckpil/blog/user/UserController.java index 2955d444..7ae2c1be 100644 --- a/testing-spring-boot-applications-with-mockmvc/src/main/java/de/rieckpil/blog/user/UserController.java +++ b/testing-spring-boot-applications-with-mockmvc/src/main/java/de/rieckpil/blog/user/UserController.java @@ -1,13 +1,12 @@ package de.rieckpil.blog.user; +import jakarta.validation.Valid; +import java.util.List; import org.springframework.http.ResponseEntity; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import org.springframework.web.util.UriComponentsBuilder; -import javax.validation.Valid; -import java.util.List; - @Validated @RestController @RequestMapping("/api/users") @@ -31,10 +30,11 @@ public User getUserByUsername(@PathVariable String username) { } @PostMapping - public ResponseEntity createNewUser(@RequestBody @Valid User user, UriComponentsBuilder uriComponentsBuilder) { + public ResponseEntity createNewUser( + @RequestBody @Valid User user, UriComponentsBuilder uriComponentsBuilder) { this.userService.storeNewUser(user); - return ResponseEntity - .created(uriComponentsBuilder.path("/api/users/{username}").build(user.getUsername())) - .build(); + return ResponseEntity.created( + uriComponentsBuilder.path("/api/users/{username}").build(user.getUsername())) + .build(); } } diff --git a/testing-spring-boot-applications-with-mockmvc/src/main/java/de/rieckpil/blog/user/UserService.java b/testing-spring-boot-applications-with-mockmvc/src/main/java/de/rieckpil/blog/user/UserService.java index ca7354ea..a32f3c44 100644 --- a/testing-spring-boot-applications-with-mockmvc/src/main/java/de/rieckpil/blog/user/UserService.java +++ b/testing-spring-boot-applications-with-mockmvc/src/main/java/de/rieckpil/blog/user/UserService.java @@ -1,10 +1,9 @@ package de.rieckpil.blog.user; -import org.springframework.stereotype.Service; - -import javax.annotation.PostConstruct; +import jakarta.annotation.PostConstruct; import java.util.ArrayList; import java.util.List; +import org.springframework.stereotype.Service; @Service public class UserService { @@ -23,9 +22,9 @@ public List getAllUsers() { public User getUserByUsername(String username) { return inMemoryUserList.stream() - .filter(user -> user.getUsername().equals(username)) - .findFirst() - .orElseThrow(() -> new UserNotFoundException("Can't find this user *sad smiley*")); + .filter(user -> user.getUsername().equals(username)) + .findFirst() + .orElseThrow(() -> new UserNotFoundException("Can't find this user *sad smiley*")); } public void storeNewUser(User user) { diff --git a/testing-spring-boot-applications-with-mockmvc/src/test/java/de/rieckpil/blog/ApplicationTest.java b/testing-spring-boot-applications-with-mockmvc/src/test/java/de/rieckpil/blog/ApplicationTest.java index 6660a3cb..804a3803 100644 --- a/testing-spring-boot-applications-with-mockmvc/src/test/java/de/rieckpil/blog/ApplicationTest.java +++ b/testing-spring-boot-applications-with-mockmvc/src/test/java/de/rieckpil/blog/ApplicationTest.java @@ -1,5 +1,9 @@ package de.rieckpil.blog; +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; @@ -7,25 +11,20 @@ import org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors; import org.springframework.test.web.servlet.MockMvc; -import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - @SpringBootTest @AutoConfigureMockMvc class ApplicationTest { - @Autowired - private MockMvc mockMvc; + @Autowired private MockMvc mockMvc; @Test public void shouldAllowDeletingReviewsWhenUserIsAdmin() throws Exception { this.mockMvc - .perform( - delete("/api/tasks/42") - .with(SecurityMockMvcRequestPostProcessors.user("duke").roles("ADMIN", "SUPER_USER")) - .with(csrf()) - ) - .andExpect(status().isOk()); + .perform( + delete("/api/tasks/42") + .with( + SecurityMockMvcRequestPostProcessors.user("duke").roles("ADMIN", "SUPER_USER")) + .with(csrf())) + .andExpect(status().isOk()); } } diff --git a/testing-spring-boot-applications-with-mockmvc/src/test/java/de/rieckpil/blog/dashboard/DashboardControllerTest.java b/testing-spring-boot-applications-with-mockmvc/src/test/java/de/rieckpil/blog/dashboard/DashboardControllerTest.java index 2bd77731..74b425bf 100644 --- a/testing-spring-boot-applications-with-mockmvc/src/test/java/de/rieckpil/blog/dashboard/DashboardControllerTest.java +++ b/testing-spring-boot-applications-with-mockmvc/src/test/java/de/rieckpil/blog/dashboard/DashboardControllerTest.java @@ -1,35 +1,36 @@ package de.rieckpil.blog.dashboard; +import static org.mockito.Mockito.when; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +import de.rieckpil.blog.SecurityConfig; import org.hamcrest.Matchers; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.context.annotation.Import; import org.springframework.test.web.servlet.MockMvc; -import static org.mockito.Mockito.when; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; - +@Import(SecurityConfig.class) @WebMvcTest(DashboardController.class) class DashboardControllerTest { - @Autowired - private MockMvc mockMvc; + @Autowired private MockMvc mockMvc; - @MockBean - private DashboardService dashboardService; + @MockBean private DashboardService dashboardService; @Test public void shouldReturnViewWithPrefilledData() throws Exception { - when(dashboardService.getAnalyticsGraphData()).thenReturn(new Integer[]{13, 42}); + when(dashboardService.getAnalyticsGraphData()).thenReturn(new Integer[] {13, 42}); this.mockMvc - .perform(get("/dashboard")) - .andExpect(status().isOk()) - .andExpect(view().name("dashboard")) - .andExpect(model().attribute("user", "Duke")) - .andExpect(model().attribute("analyticsGraph", Matchers.arrayContaining(13, 42))) - .andExpect(model().attributeExists("quickNote")); + .perform(get("/dashboard")) + .andExpect(status().isOk()) + .andExpect(view().name("dashboard")) + .andExpect(model().attribute("user", "Duke")) + .andExpect(model().attribute("analyticsGraph", Matchers.arrayContaining(13, 42))) + .andExpect(model().attributeExists("quickNote")); } } diff --git a/testing-spring-boot-applications-with-mockmvc/src/test/java/de/rieckpil/blog/task/TaskControllerSecondTest.java b/testing-spring-boot-applications-with-mockmvc/src/test/java/de/rieckpil/blog/task/TaskControllerSecondTest.java index 109d411f..e792d809 100644 --- a/testing-spring-boot-applications-with-mockmvc/src/test/java/de/rieckpil/blog/task/TaskControllerSecondTest.java +++ b/testing-spring-boot-applications-with-mockmvc/src/test/java/de/rieckpil/blog/task/TaskControllerSecondTest.java @@ -1,54 +1,50 @@ package de.rieckpil.blog.task; +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; +import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import de.rieckpil.blog.SecurityConfig; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.context.annotation.Import; import org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.web.context.WebApplicationContext; -import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; -import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - +@Import(SecurityConfig.class) @WebMvcTest(TaskController.class) public class TaskControllerSecondTest { - @Autowired - private WebApplicationContext context; + @Autowired private WebApplicationContext context; - @MockBean - private TaskService taskService; + @MockBean private TaskService taskService; protected MockMvc mockMvc; @BeforeEach public void setup() { - this.mockMvc = MockMvcBuilders - .webAppContextSetup(this.context) - .apply(springSecurity()) - .build(); + this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context).apply(springSecurity()).build(); } @Test public void shouldRejectDeletingReviewsWhenUserIsNotAdmin() throws Exception { - this.mockMvc - .perform(delete("/api/tasks/42").with(csrf())) - .andExpect(status().isUnauthorized()); + this.mockMvc.perform(delete("/api/tasks/42").with(csrf())).andExpect(status().isUnauthorized()); } @Test public void shouldAllowDeletingReviewsWhenUserIsAdmin() throws Exception { this.mockMvc - .perform( - delete("/api/tasks/42") - .with(SecurityMockMvcRequestPostProcessors.user("duke").roles("ADMIN", "SUPER_USER")) - .with(csrf()) - ) - .andExpect(status().isOk()); + .perform( + delete("/api/tasks/42") + .with( + SecurityMockMvcRequestPostProcessors.user("duke").roles("ADMIN", "SUPER_USER")) + .with(csrf())) + .andExpect(status().isOk()); } } diff --git a/testing-spring-boot-applications-with-mockmvc/src/test/java/de/rieckpil/blog/task/TaskControllerTest.java b/testing-spring-boot-applications-with-mockmvc/src/test/java/de/rieckpil/blog/task/TaskControllerTest.java index d732a4f1..04a36050 100644 --- a/testing-spring-boot-applications-with-mockmvc/src/test/java/de/rieckpil/blog/task/TaskControllerTest.java +++ b/testing-spring-boot-applications-with-mockmvc/src/test/java/de/rieckpil/blog/task/TaskControllerTest.java @@ -1,15 +1,5 @@ package de.rieckpil.blog.task; -import org.hamcrest.Matchers; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.http.MediaType; -import org.springframework.security.test.context.support.WithMockUser; -import org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors; -import org.springframework.test.web.servlet.MockMvc; - import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -20,62 +10,70 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import de.rieckpil.blog.SecurityConfig; +import org.hamcrest.Matchers; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.context.annotation.Import; +import org.springframework.http.MediaType; +import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors; +import org.springframework.test.web.servlet.MockMvc; + +@Import(SecurityConfig.class) @WebMvcTest(TaskController.class) class TaskControllerTest { - @Autowired - private MockMvc mockMvc; + @Autowired private MockMvc mockMvc; - @MockBean - private TaskService taskService; + @MockBean private TaskService taskService; @Test public void shouldRejectCreatingReviewsWhenUserIsAnonymous() throws Exception { this.mockMvc - .perform( - post("/api/tasks") - .contentType(MediaType.APPLICATION_JSON) - .content("{\"taskTitle\": \"Learn MockMvc\"}") - .with(csrf()) - ) - .andExpect(status().isUnauthorized()); + .perform( + post("/api/tasks") + .contentType(MediaType.APPLICATION_JSON) + .content("{\"taskTitle\": \"Learn MockMvc\"}") + .with(csrf())) + .andExpect(status().isUnauthorized()); } @Test - public void shouldReturnLocationOfReviewWhenUserIsAuthenticatedAndCreatesReview() throws Exception { + public void shouldReturnLocationOfReviewWhenUserIsAuthenticatedAndCreatesReview() + throws Exception { when(taskService.createTask(anyString())).thenReturn(42L); this.mockMvc - .perform( - post("/api/tasks") - .contentType(MediaType.APPLICATION_JSON) - .content("{\"taskTitle\": \"Learn MockMvc\"}") - .with(csrf()) - .with(user("duke")) - ) - .andExpect(status().isCreated()) - .andExpect(header().exists("Location")) - .andExpect(header().string("Location", Matchers.containsString("42"))); + .perform( + post("/api/tasks") + .contentType(MediaType.APPLICATION_JSON) + .content("{\"taskTitle\": \"Learn MockMvc\"}") + .with(csrf()) + .with(user("duke"))) + .andExpect(status().isCreated()) + .andExpect(header().exists("Location")) + .andExpect(header().string("Location", Matchers.containsString("42"))); } @Test @WithMockUser("duke") public void shouldRejectDeletingReviewsWhenUserLacksAdminRole() throws Exception { - this.mockMvc - .perform(delete("/api/tasks/42")) - .andExpect(status().isForbidden()); + this.mockMvc.perform(delete("/api/tasks/42")).andExpect(status().isForbidden()); } @Test public void shouldAllowDeletingReviewsWhenUserIsAdmin() throws Exception { this.mockMvc - .perform( - delete("/api/tasks/42") - .with(SecurityMockMvcRequestPostProcessors.user("duke").roles("ADMIN", "SUPER_USER")) - .with(csrf()) - ) - .andExpect(status().isOk()); + .perform( + delete("/api/tasks/42") + .with( + SecurityMockMvcRequestPostProcessors.user("duke").roles("ADMIN", "SUPER_USER")) + .with(csrf())) + .andExpect(status().isOk()); verify(taskService).deleteTask(42L); } diff --git a/testing-spring-boot-applications-with-mockmvc/src/test/java/de/rieckpil/blog/user/UserControllerTest.java b/testing-spring-boot-applications-with-mockmvc/src/test/java/de/rieckpil/blog/user/UserControllerTest.java index eeb5678a..4a91bd0d 100644 --- a/testing-spring-boot-applications-with-mockmvc/src/test/java/de/rieckpil/blog/user/UserControllerTest.java +++ b/testing-spring-boot-applications-with-mockmvc/src/test/java/de/rieckpil/blog/user/UserControllerTest.java @@ -1,70 +1,66 @@ package de.rieckpil.blog.user; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import de.rieckpil.blog.SecurityConfig; +import java.util.List; import org.hamcrest.Matchers; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.context.annotation.Import; import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.result.MockMvcResultMatchers; -import java.util.List; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; -import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - +@Import(SecurityConfig.class) @WebMvcTest(UserController.class) class UserControllerTest { - @Autowired - private MockMvc mockMvc; + @Autowired private MockMvc mockMvc; - @MockBean - private UserService userService; + @MockBean private UserService userService; @Test public void shouldReturnAllUsersForUnauthenticatedUsers() throws Exception { - when(userService.getAllUsers()) - .thenReturn(List.of(new User("duke", "duke@spring.io"))); + when(userService.getAllUsers()).thenReturn(List.of(new User("duke", "duke@spring.io"))); this.mockMvc - .perform(MockMvcRequestBuilders.get("/api/users")) - .andExpect(MockMvcResultMatchers.status().isOk()) - .andExpect(MockMvcResultMatchers.jsonPath("$.size()").value(1)) - .andExpect(MockMvcResultMatchers.jsonPath("$[0].username").value("duke")) - .andExpect(MockMvcResultMatchers.jsonPath("$[0].email").value("duke@spring.io")); + .perform(MockMvcRequestBuilders.get("/api/users")) + .andExpect(MockMvcResultMatchers.status().isOk()) + .andExpect(MockMvcResultMatchers.jsonPath("$.size()").value(1)) + .andExpect(MockMvcResultMatchers.jsonPath("$[0].username").value("duke")) + .andExpect(MockMvcResultMatchers.jsonPath("$[0].email").value("duke@spring.io")); } @Test public void shouldReturn404WhenUserIsNotFound() throws Exception { when(userService.getUserByUsername("duke")) - .thenThrow(new UserNotFoundException("duke is not found")); + .thenThrow(new UserNotFoundException("duke is not found")); - this.mockMvc - .perform(get("/api/users/duke")) - .andExpect(status().isNotFound()); + this.mockMvc.perform(get("/api/users/duke")).andExpect(status().isNotFound()); } @Test public void shouldAllowCreationForUnauthenticatedUsers() throws Exception { this.mockMvc - .perform( - post("/api/users") - .contentType(MediaType.APPLICATION_JSON) - .content("{\"username\": \"duke\", \"email\":\"duke@spring.io\"}") - .with(csrf()) - ) - .andExpect(status().isCreated()) - .andExpect(header().exists("Location")) - .andExpect(header().string("Location", Matchers.containsString("duke"))); + .perform( + post("/api/users") + .contentType(MediaType.APPLICATION_JSON) + .content("{\"username\": \"duke\", \"email\":\"duke@spring.io\"}") + .with(csrf())) + .andExpect(status().isCreated()) + .andExpect(header().exists("Location")) + .andExpect(header().string("Location", Matchers.containsString("duke"))); verify(userService).storeNewUser(any(User.class)); } diff --git a/testing-spring-rest-template/pom.xml b/testing-spring-rest-template/pom.xml index 63a1f67d..4617d3b2 100644 --- a/testing-spring-rest-template/pom.xml +++ b/testing-spring-rest-template/pom.xml @@ -2,23 +2,19 @@ 4.0.0 + - org.springframework.boot - spring-boot-starter-parent - 2.4.5 - + de.rieckpil.blog + blog-parent + 0.0.1-SNAPSHOT + ../pom.xml - de.rieckpil.blog testing-spring-rest-template 0.0.1-SNAPSHOT testing-spring-rest-template Demo project for Spring Boot - - 16 - - org.springframework.boot diff --git a/testing-spring-rest-template/src/main/java/de/rieckpil/blog/RestTemplateConfig.java b/testing-spring-rest-template/src/main/java/de/rieckpil/blog/RestTemplateConfig.java index 44a171e6..cffe522b 100644 --- a/testing-spring-rest-template/src/main/java/de/rieckpil/blog/RestTemplateConfig.java +++ b/testing-spring-rest-template/src/main/java/de/rieckpil/blog/RestTemplateConfig.java @@ -1,20 +1,20 @@ package de.rieckpil.blog; +import java.time.Duration; import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.client.RestTemplate; -import java.time.Duration; - @Configuration public class RestTemplateConfig { @Bean public RestTemplate reqresRestTemplate(RestTemplateBuilder restTemplateBuilder) { - return restTemplateBuilder.rootUri("https://reqres.in/") - .setConnectTimeout(Duration.ofSeconds(2)) - .setReadTimeout(Duration.ofSeconds(2)) - .build(); + return restTemplateBuilder + .rootUri("https://reqres.in/") + .setConnectTimeout(Duration.ofSeconds(2)) + .setReadTimeout(Duration.ofSeconds(2)) + .build(); } } diff --git a/testing-spring-rest-template/src/main/java/de/rieckpil/blog/TestingSpringRestTemplateApplication.java b/testing-spring-rest-template/src/main/java/de/rieckpil/blog/TestingSpringRestTemplateApplication.java index e0dab9b8..7ea961ff 100644 --- a/testing-spring-rest-template/src/main/java/de/rieckpil/blog/TestingSpringRestTemplateApplication.java +++ b/testing-spring-rest-template/src/main/java/de/rieckpil/blog/TestingSpringRestTemplateApplication.java @@ -4,10 +4,9 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication -public class TestingSpringRestTemplateApplication{ +public class TestingSpringRestTemplateApplication { public static void main(String[] args) { SpringApplication.run(TestingSpringRestTemplateApplication.class, args); } - } diff --git a/testing-spring-rest-template/src/main/java/de/rieckpil/blog/User.java b/testing-spring-rest-template/src/main/java/de/rieckpil/blog/User.java index 643a435f..cd409fc3 100644 --- a/testing-spring-rest-template/src/main/java/de/rieckpil/blog/User.java +++ b/testing-spring-rest-template/src/main/java/de/rieckpil/blog/User.java @@ -3,9 +3,7 @@ public class User { private UserData data; - public User() { - - } + public User() {} public User(UserData data) { this.data = data; @@ -21,8 +19,6 @@ public void setData(UserData data) { @Override public String toString() { - return "User{" + - "data=" + data + - '}'; + return "User{" + "data=" + data + '}'; } } diff --git a/testing-spring-rest-template/src/main/java/de/rieckpil/blog/UserClient.java b/testing-spring-rest-template/src/main/java/de/rieckpil/blog/UserClient.java index 3b8807e8..87ebd98b 100644 --- a/testing-spring-rest-template/src/main/java/de/rieckpil/blog/UserClient.java +++ b/testing-spring-rest-template/src/main/java/de/rieckpil/blog/UserClient.java @@ -24,8 +24,7 @@ public User getSingleUser(Long id) { HttpEntity requestEntity = new HttpEntity<>(headers); return this.restTemplate - .exchange("/api/users/{id}", HttpMethod.GET, requestEntity, User.class, id) - .getBody(); - + .exchange("/api/users/{id}", HttpMethod.GET, requestEntity, User.class, id) + .getBody(); } } diff --git a/testing-spring-rest-template/src/main/java/de/rieckpil/blog/UserData.java b/testing-spring-rest-template/src/main/java/de/rieckpil/blog/UserData.java index bf01801d..99a934fe 100644 --- a/testing-spring-rest-template/src/main/java/de/rieckpil/blog/UserData.java +++ b/testing-spring-rest-template/src/main/java/de/rieckpil/blog/UserData.java @@ -68,12 +68,21 @@ public void setAvatar(String avatar) { @Override public String toString() { - return "UserData{" + - "id=" + id + - ", email='" + email + '\'' + - ", avatar='" + avatar + '\'' + - ", firstName='" + firstName + '\'' + - ", lastName='" + lastName + '\'' + - '}'; + return "UserData{" + + "id=" + + id + + ", email='" + + email + + '\'' + + ", avatar='" + + avatar + + '\'' + + ", firstName='" + + firstName + + '\'' + + ", lastName='" + + lastName + + '\'' + + '}'; } } diff --git a/testing-spring-rest-template/src/test/java/de/rieckpil/blog/ResourceClientTest.java b/testing-spring-rest-template/src/test/java/de/rieckpil/blog/ResourceClientTest.java index 08838eeb..aadb2583 100644 --- a/testing-spring-rest-template/src/test/java/de/rieckpil/blog/ResourceClientTest.java +++ b/testing-spring-rest-template/src/test/java/de/rieckpil/blog/ResourceClientTest.java @@ -1,5 +1,9 @@ package de.rieckpil.blog; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo; +import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess; + import com.fasterxml.jackson.databind.JsonNode; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -10,28 +14,22 @@ import org.springframework.http.MediaType; import org.springframework.test.web.client.MockRestServiceServer; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo; -import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess; - @RestClientTest(ResourceClient.class) @AutoConfigureWebClient(registerRestTemplate = true) class ResourceClientTest { - @Autowired - private ResourceClient resourceClient; + @Autowired private ResourceClient resourceClient; - @Autowired - private MockRestServiceServer mockRestServiceServer; + @Autowired private MockRestServiceServer mockRestServiceServer; @BeforeEach - // @Before for JUnit 4 + // @Before for JUnit 4 void setUp() { this.mockRestServiceServer.reset(); } @AfterEach - // @After for JUnit 4 + // @After for JUnit 4 void tearDown() { this.mockRestServiceServer.verify(); } @@ -46,8 +44,8 @@ void successfullyReturnData() { """; this.mockRestServiceServer - .expect(requestTo("/api/unkown/1")) - .andRespond(withSuccess(json, MediaType.APPLICATION_JSON)); + .expect(requestTo("/api/unkown/1")) + .andRespond(withSuccess(json, MediaType.APPLICATION_JSON)); JsonNode result = resourceClient.getSingleResource(1L); diff --git a/testing-spring-rest-template/src/test/java/de/rieckpil/blog/TestingSpringRestTemplateApplicationTests.java b/testing-spring-rest-template/src/test/java/de/rieckpil/blog/TestingSpringRestTemplateApplicationTests.java index 2c4994f2..322063d0 100644 --- a/testing-spring-rest-template/src/test/java/de/rieckpil/blog/TestingSpringRestTemplateApplicationTests.java +++ b/testing-spring-rest-template/src/test/java/de/rieckpil/blog/TestingSpringRestTemplateApplicationTests.java @@ -6,8 +6,6 @@ @SpringBootTest class TestingSpringRestTemplateApplicationTests { - @Test - void contextLoads() { - } - + @Test + void contextLoads() {} } diff --git a/testing-spring-rest-template/src/test/java/de/rieckpil/blog/UserClientTest.java b/testing-spring-rest-template/src/test/java/de/rieckpil/blog/UserClientTest.java index 86f030de..94d722c8 100644 --- a/testing-spring-rest-template/src/test/java/de/rieckpil/blog/UserClientTest.java +++ b/testing-spring-rest-template/src/test/java/de/rieckpil/blog/UserClientTest.java @@ -1,5 +1,9 @@ package de.rieckpil.blog; +import static org.junit.jupiter.api.Assertions.*; +import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo; +import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess; + import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -10,26 +14,20 @@ import org.springframework.test.web.client.response.MockRestResponseCreators; import org.springframework.web.client.HttpClientErrorException; -import static org.junit.jupiter.api.Assertions.*; -import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo; -import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess; - @RestClientTest(UserClient.class) class UserClientTest { - @Autowired - private UserClient userClient; + @Autowired private UserClient userClient; - @Autowired - private ObjectMapper objectMapper; + @Autowired private ObjectMapper objectMapper; - @Autowired - private MockRestServiceServer mockRestServiceServer; + @Autowired private MockRestServiceServer mockRestServiceServer; @Test void userClientSuccessfullyReturnsUser() { - String json = """ + String json = + """ { "data": { "id": 1, @@ -42,8 +40,8 @@ void userClientSuccessfullyReturnsUser() { """; this.mockRestServiceServer - .expect(requestTo("/api/users/1")) - .andRespond(withSuccess(json, MediaType.APPLICATION_JSON)); + .expect(requestTo("/api/users/1")) + .andRespond(withSuccess(json, MediaType.APPLICATION_JSON)); User result = userClient.getSingleUser(1L); @@ -53,12 +51,13 @@ void userClientSuccessfullyReturnsUser() { @Test void userClientSuccessfullyReturnsUserDuke() throws Exception { - String json = this.objectMapper - .writeValueAsString(new User(new UserData(42L, "duke@java.org", "duke", "duke", "duke"))); + String json = + this.objectMapper.writeValueAsString( + new User(new UserData(42L, "duke@java.org", "duke", "duke", "duke"))); this.mockRestServiceServer - .expect(requestTo("/api/users/42")) - .andRespond(withSuccess(json, MediaType.APPLICATION_JSON)); + .expect(requestTo("/api/users/42")) + .andRespond(withSuccess(json, MediaType.APPLICATION_JSON)); User result = userClient.getSingleUser(42L); @@ -71,10 +70,10 @@ void userClientSuccessfullyReturnsUserDuke() throws Exception { @Test void userClientThrowsExceptionWhenNoUserIsFound() { - this.mockRestServiceServer.expect(requestTo("/api/users/1")) - .andRespond(MockRestResponseCreators.withStatus(HttpStatus.NOT_FOUND)); + this.mockRestServiceServer + .expect(requestTo("/api/users/1")) + .andRespond(MockRestResponseCreators.withStatus(HttpStatus.NOT_FOUND)); assertThrows(HttpClientErrorException.class, () -> userClient.getSingleUser(1L)); } - } diff --git a/whats-new-in-spring-boot-2.1/pom.xml b/whats-new-in-spring-boot-2.1/pom.xml index ed4b7e5e..95f88569 100644 --- a/whats-new-in-spring-boot-2.1/pom.xml +++ b/whats-new-in-spring-boot-2.1/pom.xml @@ -1,76 +1,71 @@ - - 4.0.0 + + 4.0.0 - de.rieckpil.blog - whats-new-in-spring-boot-2.1 - 0.0.1-SNAPSHOT - jar + + de.rieckpil.blog + blog-parent + 0.0.1-SNAPSHOT + ../pom.xml + - whats-new-in-spring-boot-2.1 - Updates to Spring Boot 2.1 + whats-new-in-spring-boot-2.1 + 0.0.1-SNAPSHOT + jar - - org.springframework.boot - spring-boot-starter-parent - 2.1.0.RELEASE - - + whats-new-in-spring-boot-2.1 + Updates to Spring Boot 2.1 - - UTF-8 - UTF-8 - 11 - + + UTF-8 + UTF-8 + - - - org.springframework.boot - spring-boot-starter-data-jpa - - - org.springframework.boot - spring-boot-starter-web - + + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.springframework.boot + spring-boot-starter-web + - - com.h2database - h2 - runtime - - - org.springframework.boot - spring-boot-starter-test - test - - - junit - junit - - - - - org.junit.jupiter - junit-jupiter-api - test - - - org.junit.jupiter - junit-jupiter-engine - test - - - - - - - org.springframework.boot - spring-boot-maven-plugin - - - + + com.h2database + h2 + runtime + + + org.springframework.boot + spring-boot-starter-test + test + + + junit + junit + + + + + org.junit.jupiter + junit-jupiter-api + test + + + org.junit.jupiter + junit-jupiter-engine + test + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + diff --git a/whats-new-in-spring-boot-2.1/src/main/java/de/rieckpil/learning/Application.java b/whats-new-in-spring-boot-2.1/src/main/java/de/rieckpil/learning/Application.java index 46353304..55688540 100644 --- a/whats-new-in-spring-boot-2.1/src/main/java/de/rieckpil/learning/Application.java +++ b/whats-new-in-spring-boot-2.1/src/main/java/de/rieckpil/learning/Application.java @@ -6,7 +6,7 @@ @SpringBootApplication public class Application { - public static void main(String[] args) { - SpringApplication.run(Application.class, args); - } + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } } diff --git a/whats-new-in-spring-boot-2.1/src/main/java/de/rieckpil/learning/User.java b/whats-new-in-spring-boot-2.1/src/main/java/de/rieckpil/learning/User.java index 33a8c05c..e61f04f1 100644 --- a/whats-new-in-spring-boot-2.1/src/main/java/de/rieckpil/learning/User.java +++ b/whats-new-in-spring-boot-2.1/src/main/java/de/rieckpil/learning/User.java @@ -1,48 +1,50 @@ -package de.rieckpil.learning; - -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; - -@Entity -public class User { - - @Id - @GeneratedValue - private Long id; - private String name; - private String userId; - - public User() { - } - - public User(String name, String userId) { - this.name = name; - this.userId = userId; - } - - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getUserId() { - return userId; - } - - public void setUserId(String userId) { - this.userId = userId; - } - -} +package de.rieckpil.learning; + +import jakarta.persistence.Entity; +import jakarta.persistence.Id; + +@Entity +public class User { + + @Id private Long id; + + private String name; + private String userId; + + public User() {} + + public User(Long id, String name, String userId) { + this.id = id; + this.name = name; + this.userId = userId; + } + + public User(String name, String userId) { + this.name = name; + this.userId = userId; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } +} diff --git a/whats-new-in-spring-boot-2.1/src/main/java/de/rieckpil/learning/UserPopulator.java b/whats-new-in-spring-boot-2.1/src/main/java/de/rieckpil/learning/UserPopulator.java index 9bb4ed18..cd00c9e3 100644 --- a/whats-new-in-spring-boot-2.1/src/main/java/de/rieckpil/learning/UserPopulator.java +++ b/whats-new-in-spring-boot-2.1/src/main/java/de/rieckpil/learning/UserPopulator.java @@ -1,24 +1,27 @@ -package de.rieckpil.learning; - -import java.util.List; -import java.util.UUID; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.CommandLineRunner; -import org.springframework.stereotype.Service; - -@Service -public class UserPopulator implements CommandLineRunner { - - @Autowired - UserRepository userRepository; - - @Override - public void run(String... args) throws Exception { - - List.of("Tom", "Mike", "John", "Andrew").stream() - .forEach(n -> userRepository.save(new User(n, UUID.randomUUID().toString()))); - - } - -} +package de.rieckpil.learning; + +import java.util.List; +import java.util.UUID; +import java.util.concurrent.ThreadLocalRandom; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.stereotype.Service; + +@Service +public class UserPopulator implements CommandLineRunner { + + @Autowired UserRepository userRepository; + + @Override + public void run(String... args) throws Exception { + + List.of("Tom", "Mike", "John", "Andrew").stream() + .forEach( + n -> + userRepository.save( + new User( + ThreadLocalRandom.current().nextLong(1, 99999), + n, + UUID.randomUUID().toString()))); + } +} diff --git a/whats-new-in-spring-boot-2.1/src/main/java/de/rieckpil/learning/UserRepository.java b/whats-new-in-spring-boot-2.1/src/main/java/de/rieckpil/learning/UserRepository.java index 5c7f4771..2369fad1 100644 --- a/whats-new-in-spring-boot-2.1/src/main/java/de/rieckpil/learning/UserRepository.java +++ b/whats-new-in-spring-boot-2.1/src/main/java/de/rieckpil/learning/UserRepository.java @@ -1,7 +1,5 @@ -package de.rieckpil.learning; - -import org.springframework.data.jpa.repository.JpaRepository; - -public interface UserRepository extends JpaRepository { - -} +package de.rieckpil.learning; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface UserRepository extends JpaRepository {} diff --git a/whats-new-in-spring-boot-2.1/src/test/java/de/rieckpil/learning/ApplicationTests.java b/whats-new-in-spring-boot-2.1/src/test/java/de/rieckpil/learning/ApplicationTests.java index befa5bdc..a36eb946 100644 --- a/whats-new-in-spring-boot-2.1/src/test/java/de/rieckpil/learning/ApplicationTests.java +++ b/whats-new-in-spring-boot-2.1/src/test/java/de/rieckpil/learning/ApplicationTests.java @@ -1,16 +1,16 @@ package de.rieckpil.learning; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; +@Disabled @SpringBootTest // no @ExtendWith(SpringExtension.class) needed -public class ApplicationTests { - - @Test - @DisplayName("Load the whole Spring context") - public void contextLoads() { - } +class ApplicationTests { + @Test + @DisplayName("Load the whole Spring context") + void contextLoads() {} } diff --git a/whats-new-in-spring-boot-2.2/pom.xml b/whats-new-in-spring-boot-2.2/pom.xml index 8a943833..2bcccdfd 100644 --- a/whats-new-in-spring-boot-2.2/pom.xml +++ b/whats-new-in-spring-boot-2.2/pom.xml @@ -3,22 +3,19 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - - org.springframework.boot - spring-boot-starter-parent - 2.2.0.RELEASE - - + + de.rieckpil.blog + blog-parent + 0.0.1-SNAPSHOT + ../pom.xml + + whats-new-in-spring-boot.2.2 0.0.1-SNAPSHOT - whats-new-in-spring-boot.2.2 + whats-new-in-spring-boot-2.2 What's new in Spring Boot 2.2 - - 11 - - org.springframework.boot diff --git a/whats-new-in-spring-boot-2.2/src/main/java/de/rieckpil/blog/Application.java b/whats-new-in-spring-boot-2.2/src/main/java/de/rieckpil/blog/Application.java index 0d8a1e8f..4c8cfd9d 100644 --- a/whats-new-in-spring-boot-2.2/src/main/java/de/rieckpil/blog/Application.java +++ b/whats-new-in-spring-boot-2.2/src/main/java/de/rieckpil/blog/Application.java @@ -7,12 +7,10 @@ @SpringBootApplication public class Application implements CommandLineRunner { - public static void main(String[] args) { - SpringApplication.run(Application.class, args); - } - - @Override - public void run(String... args) throws Exception { - } + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + @Override + public void run(String... args) throws Exception {} } diff --git a/whats-new-in-spring-boot-2.2/src/main/java/de/rieckpil/blog/CustomLivenessCheck.java b/whats-new-in-spring-boot-2.2/src/main/java/de/rieckpil/blog/CustomLivenessCheck.java index bc056d9a..46fab7ca 100644 --- a/whats-new-in-spring-boot-2.2/src/main/java/de/rieckpil/blog/CustomLivenessCheck.java +++ b/whats-new-in-spring-boot-2.2/src/main/java/de/rieckpil/blog/CustomLivenessCheck.java @@ -1,24 +1,22 @@ package de.rieckpil.blog; +import java.util.concurrent.ThreadLocalRandom; import org.springframework.boot.actuate.health.Health; import org.springframework.boot.actuate.health.HealthIndicator; import org.springframework.stereotype.Component; -import java.util.concurrent.ThreadLocalRandom; - @Component("custom-liveness") public class CustomLivenessCheck implements HealthIndicator { - @Override - public Health health() { - if (checkLiveness()) { - return Health.up().build(); - } - return Health.down().withDetail("Error Code", 42).build(); - } - - private boolean checkLiveness() { - return ThreadLocalRandom.current().nextBoolean(); + @Override + public Health health() { + if (checkLiveness()) { + return Health.up().build(); } + return Health.down().withDetail("Error Code", 42).build(); + } -} \ No newline at end of file + private boolean checkLiveness() { + return ThreadLocalRandom.current().nextBoolean(); + } +} diff --git a/whats-new-in-spring-boot-2.2/src/main/java/de/rieckpil/blog/KubernetesDetector.java b/whats-new-in-spring-boot-2.2/src/main/java/de/rieckpil/blog/KubernetesDetector.java index 5fbc28d8..16219caf 100644 --- a/whats-new-in-spring-boot-2.2/src/main/java/de/rieckpil/blog/KubernetesDetector.java +++ b/whats-new-in-spring-boot-2.2/src/main/java/de/rieckpil/blog/KubernetesDetector.java @@ -9,9 +9,8 @@ @ConditionalOnCloudPlatform(CloudPlatform.KUBERNETES) public class KubernetesDetector implements CommandLineRunner { - @Override - public void run(String... args) throws Exception { - System.out.println("--- You are running on KUBERNETES ;)"); - } - + @Override + public void run(String... args) throws Exception { + System.out.println("--- You are running on KUBERNETES ;)"); + } } diff --git a/whats-new-in-spring-boot-2.2/src/main/java/de/rieckpil/blog/SampleEndpoint.java b/whats-new-in-spring-boot-2.2/src/main/java/de/rieckpil/blog/SampleEndpoint.java index 3b007320..f1ecc4dc 100644 --- a/whats-new-in-spring-boot-2.2/src/main/java/de/rieckpil/blog/SampleEndpoint.java +++ b/whats-new-in-spring-boot-2.2/src/main/java/de/rieckpil/blog/SampleEndpoint.java @@ -1,27 +1,26 @@ package de.rieckpil.blog; +import jakarta.annotation.PostConstruct; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; -import javax.annotation.PostConstruct; - @RestController public class SampleEndpoint { - private SampleService sampleService; + private SampleService sampleService; - private SampleEndpoint(SampleService sampleService) { - this.sampleService = sampleService; - } + private SampleEndpoint(SampleService sampleService) { + this.sampleService = sampleService; + } - @PostConstruct - public void init() { - System.out.println("SampleEndpoint is now initialized"); - } + @PostConstruct + public void init() { + System.out.println("SampleEndpoint is now initialized"); + } - @GetMapping("/hello") - public ResponseEntity sayHello() { - return ResponseEntity.ok(sampleService.getMessage()); - } + @GetMapping("/hello") + public ResponseEntity sayHello() { + return ResponseEntity.ok(sampleService.getMessage()); + } } diff --git a/whats-new-in-spring-boot-2.2/src/main/java/de/rieckpil/blog/SampleService.java b/whats-new-in-spring-boot-2.2/src/main/java/de/rieckpil/blog/SampleService.java index 417c7589..0ccff0c3 100644 --- a/whats-new-in-spring-boot-2.2/src/main/java/de/rieckpil/blog/SampleService.java +++ b/whats-new-in-spring-boot-2.2/src/main/java/de/rieckpil/blog/SampleService.java @@ -1,20 +1,19 @@ package de.rieckpil.blog; +import jakarta.annotation.PostConstruct; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; -import javax.annotation.PostConstruct; - @Service @Lazy(false) public class SampleService { - @PostConstruct - public void init() { - System.out.println("SampleService is now initialized"); - } + @PostConstruct + public void init() { + System.out.println("SampleService is now initialized"); + } - public String getMessage() { - return "Hello World"; - } + public String getMessage() { + return "Hello World"; + } } diff --git a/whats-new-in-spring-boot-2.2/src/test/java/de/rieckpil/blog/ApplicationTests.java b/whats-new-in-spring-boot-2.2/src/test/java/de/rieckpil/blog/ApplicationTests.java index f8704546..fa726c98 100644 --- a/whats-new-in-spring-boot-2.2/src/test/java/de/rieckpil/blog/ApplicationTests.java +++ b/whats-new-in-spring-boot-2.2/src/test/java/de/rieckpil/blog/ApplicationTests.java @@ -9,8 +9,6 @@ @SpringBootTest public class ApplicationTests { - @Test - public void contextLoads() { - } - + @Test + public void contextLoads() {} } diff --git a/whats-new-in-spring-boot-2.2/src/test/java/de/rieckpil/blog/JUnit5Test.java b/whats-new-in-spring-boot-2.2/src/test/java/de/rieckpil/blog/JUnit5Test.java index 1b390bfd..6634f60b 100644 --- a/whats-new-in-spring-boot-2.2/src/test/java/de/rieckpil/blog/JUnit5Test.java +++ b/whats-new-in-spring-boot-2.2/src/test/java/de/rieckpil/blog/JUnit5Test.java @@ -1,14 +1,14 @@ package de.rieckpil.blog; -import org.junit.jupiter.api.Test; - import static org.junit.jupiter.api.Assertions.assertEquals; +import org.junit.jupiter.api.Test; + public class JUnit5Test { - @Test - public void testMe() { - var sum = 2 + 2; - assertEquals(4, sum); - } + @Test + public void testMe() { + var sum = 2 + 2; + assertEquals(4, sum); + } } diff --git a/whats-new-in-spring-boot-2.3/.java-version b/whats-new-in-spring-boot-2.3/.java-version deleted file mode 100644 index ed9d00f9..00000000 --- a/whats-new-in-spring-boot-2.3/.java-version +++ /dev/null @@ -1 +0,0 @@ -14.0 diff --git a/whats-new-in-spring-boot-2.3/pom.xml b/whats-new-in-spring-boot-2.3/pom.xml index 0633013d..2fe3bc3a 100644 --- a/whats-new-in-spring-boot-2.3/pom.xml +++ b/whats-new-in-spring-boot-2.3/pom.xml @@ -4,22 +4,17 @@ 4.0.0 - org.springframework.boot - spring-boot-starter-parent - 2.3.0.RELEASE - + de.rieckpil.blog + blog-parent + 0.0.1-SNAPSHOT + ../pom.xml - de.rieckpil.blog whats-new-in-spring-boot-2-3 0.0.1-SNAPSHOT whats-new-in-spring-boot-2-3 Updates with Spring Boot 2.3 - - 14 - - org.springframework.boot @@ -64,7 +59,7 @@ myregistry.com/rieckpil/${project.artifactId} - 14.0.1 + 21.0.1 @@ -76,24 +71,6 @@ - - org.apache.maven.plugins - maven-compiler-plugin - - - --enable-preview - - - - - org.apache.maven.plugins - maven-surefire-plugin - - - --enable-preview - - - diff --git a/whats-new-in-spring-boot-2.3/src/main/java/de/rieckpil/blog/SampleController.java b/whats-new-in-spring-boot-2.3/src/main/java/de/rieckpil/blog/SampleController.java index dfd2cabb..316ef0e6 100644 --- a/whats-new-in-spring-boot-2.3/src/main/java/de/rieckpil/blog/SampleController.java +++ b/whats-new-in-spring-boot-2.3/src/main/java/de/rieckpil/blog/SampleController.java @@ -1,33 +1,31 @@ package de.rieckpil.blog; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Positive; +import java.time.LocalDate; +import java.util.List; +import java.util.stream.Collectors; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -import javax.validation.constraints.Max; -import javax.validation.constraints.Positive; -import java.time.LocalDate; -import java.util.List; -import java.util.stream.Collectors; - @Validated @RestController public class SampleController { @GetMapping("/messages") public List getMessages(@RequestParam("size") @Positive @Max(6) Integer size) { - return List.of("Hello", "World", "Foo", "Bar", "Duke", "Spring") - .stream() - .limit(size) - .collect(Collectors.toList()); - + return List.of("Hello", "World", "Foo", "Bar", "Duke", "Spring").stream() + .limit(size) + .collect(Collectors.toList()); } @GetMapping("/users") public List getUsers() { - return List.of(new User("Duke", LocalDate.now(), true), - new User("Duke", LocalDate.now().minusDays(1), false)); + return List.of( + new User("Duke", LocalDate.now(), true), + new User("Duke", LocalDate.now().minusDays(1), false)); } @GetMapping("/api/customers") diff --git a/whats-new-in-spring-boot-2.3/src/main/java/de/rieckpil/blog/User.java b/whats-new-in-spring-boot-2.3/src/main/java/de/rieckpil/blog/User.java index a1073375..d9876ee4 100644 --- a/whats-new-in-spring-boot-2.3/src/main/java/de/rieckpil/blog/User.java +++ b/whats-new-in-spring-boot-2.3/src/main/java/de/rieckpil/blog/User.java @@ -1,10 +1,7 @@ package de.rieckpil.blog; import com.fasterxml.jackson.annotation.JsonAutoDetect; - import java.time.LocalDate; @JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY) -public record User(String name, LocalDate dateOfBirth, boolean isRegistered) { -} - +public record User(String name, LocalDate dateOfBirth, boolean isRegistered) {} diff --git a/whats-new-in-spring-boot-2.3/src/main/java/de/rieckpil/blog/WhatsNewInSpringBoot23Application.java b/whats-new-in-spring-boot-2.3/src/main/java/de/rieckpil/blog/WhatsNewInSpringBoot23Application.java index 9b60e3b9..512eb562 100644 --- a/whats-new-in-spring-boot-2.3/src/main/java/de/rieckpil/blog/WhatsNewInSpringBoot23Application.java +++ b/whats-new-in-spring-boot-2.3/src/main/java/de/rieckpil/blog/WhatsNewInSpringBoot23Application.java @@ -9,5 +9,4 @@ public class WhatsNewInSpringBoot23Application { public static void main(String[] args) { SpringApplication.run(WhatsNewInSpringBoot23Application.class, args); } - } diff --git a/whats-new-in-spring-boot-2.3/src/test/java/de/rieckpil/blog/WhatsNewInSpringBoot23ApplicationTests.java b/whats-new-in-spring-boot-2.3/src/test/java/de/rieckpil/blog/WhatsNewInSpringBoot23ApplicationTests.java index ccab3ab2..13ff41e3 100644 --- a/whats-new-in-spring-boot-2.3/src/test/java/de/rieckpil/blog/WhatsNewInSpringBoot23ApplicationTests.java +++ b/whats-new-in-spring-boot-2.3/src/test/java/de/rieckpil/blog/WhatsNewInSpringBoot23ApplicationTests.java @@ -7,7 +7,5 @@ class WhatsNewInSpringBoot23ApplicationTests { @Test - void contextLoads() { - } - + void contextLoads() {} } diff --git a/write-concise-web-tests-with-selenide/pom.xml b/write-concise-web-tests-with-selenide/pom.xml index 7b88ab63..7aabaeb1 100644 --- a/write-concise-web-tests-with-selenide/pom.xml +++ b/write-concise-web-tests-with-selenide/pom.xml @@ -2,24 +2,22 @@ 4.0.0 + - org.springframework.boot - spring-boot-starter-parent - 2.6.4 - + de.rieckpil.blog + blog-parent + 0.0.1-SNAPSHOT + ../pom.xml - de.rieckpil.blog write-concise-web-tests-with-selenide 0.0.1-SNAPSHOT write-concise-web-tests-with-selenide Concise Web Tests with Selenide - 11 - 6.3.3 - 1.16.3 - 4.3.0 + 7.0.4 + 4.16.1 @@ -58,21 +56,6 @@ - - - org.springframework.boot - spring-boot-maven-plugin - - - org.apache.maven.plugins - maven-failsafe-plugin - 3.0.0-M5 - - - **/*WT.java - - - - + diff --git a/write-concise-web-tests-with-selenide/src/main/java/de/rieckpil/blog/Application.java b/write-concise-web-tests-with-selenide/src/main/java/de/rieckpil/blog/Application.java index bd5e4c56..6511f3c1 100644 --- a/write-concise-web-tests-with-selenide/src/main/java/de/rieckpil/blog/Application.java +++ b/write-concise-web-tests-with-selenide/src/main/java/de/rieckpil/blog/Application.java @@ -9,5 +9,4 @@ public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } - } diff --git a/write-concise-web-tests-with-selenide/src/main/java/de/rieckpil/blog/Book.java b/write-concise-web-tests-with-selenide/src/main/java/de/rieckpil/blog/Book.java index 2f521a29..049caade 100644 --- a/write-concise-web-tests-with-selenide/src/main/java/de/rieckpil/blog/Book.java +++ b/write-concise-web-tests-with-selenide/src/main/java/de/rieckpil/blog/Book.java @@ -6,8 +6,7 @@ public class Book { private String isbn; private String title; - public Book() { - } + public Book() {} public Book(Long id, String isbn, String title) { this.id = id; diff --git a/write-concise-web-tests-with-selenide/src/main/java/de/rieckpil/blog/BookController.java b/write-concise-web-tests-with-selenide/src/main/java/de/rieckpil/blog/BookController.java index cbe79d27..73ad5ca0 100644 --- a/write-concise-web-tests-with-selenide/src/main/java/de/rieckpil/blog/BookController.java +++ b/write-concise-web-tests-with-selenide/src/main/java/de/rieckpil/blog/BookController.java @@ -1,11 +1,10 @@ package de.rieckpil.blog; +import java.util.List; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import java.util.List; - @RestController @RequestMapping("/api/books") public class BookController { diff --git a/write-concise-web-tests-with-selenide/src/test/java/de/rieckpil/blog/BookStoreTestcontainersWT.java b/write-concise-web-tests-with-selenide/src/test/java/de/rieckpil/blog/BookStoreTestcontainersWT.java index 4fc14c0d..6fbeca80 100644 --- a/write-concise-web-tests-with-selenide/src/test/java/de/rieckpil/blog/BookStoreTestcontainersWT.java +++ b/write-concise-web-tests-with-selenide/src/test/java/de/rieckpil/blog/BookStoreTestcontainersWT.java @@ -1,5 +1,9 @@ package de.rieckpil.blog; +import static com.codeborne.selenide.Selenide.$; +import static com.codeborne.selenide.Selenide.open; +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment; + import com.codeborne.selenide.Condition; import com.codeborne.selenide.Configuration; import com.codeborne.selenide.WebDriverRunner; @@ -12,36 +16,31 @@ import org.openqa.selenium.remote.RemoteWebDriver; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.core.env.Environment; import org.testcontainers.Testcontainers; import org.testcontainers.containers.BrowserWebDriverContainer; import org.testcontainers.utility.DockerImageName; -import static com.codeborne.selenide.Selenide.$; -import static com.codeborne.selenide.Selenide.open; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment; - @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) class BookStoreTestcontainersWT { public static BrowserWebDriverContainer webDriverContainer = - new BrowserWebDriverContainer<>( - System.getProperty("os.arch").equals("aarch64") ? - DockerImageName.parse("seleniarm/standalone-chromium") - .asCompatibleSubstituteFor("selenium/standalone-chrome") - : DockerImageName.parse("selenium/standalone-chrome:4.3.0-20220726") - ) - .withCapabilities(new ChromeOptions() - .addArguments("--no-sandbox") - .addArguments("--disable-dev-shm-usage")); + new BrowserWebDriverContainer<>( + System.getProperty("os.arch").equals("aarch64") + ? DockerImageName.parse("seleniarm/standalone-chromium") + .asCompatibleSubstituteFor("selenium/standalone-chrome") + : DockerImageName.parse("selenium/standalone-chrome")) + .withCapabilities( + new ChromeOptions() + .addArguments("--no-sandbox") + .addArguments("--disable-dev-shm-usage")); @RegisterExtension static ScreenShooterExtension screenShooterExtension = - new ScreenShooterExtension().to("target/selenide"); + new ScreenShooterExtension().to("target/selenide"); - @LocalServerPort - private Integer port; + @LocalServerPort private Integer port; @BeforeAll static void beforeAll(@Autowired Environment environment) { diff --git a/write-concise-web-tests-with-selenide/src/test/java/de/rieckpil/blog/BookStoreWT.java b/write-concise-web-tests-with-selenide/src/test/java/de/rieckpil/blog/BookStoreWT.java index a2f11565..7742124f 100644 --- a/write-concise-web-tests-with-selenide/src/test/java/de/rieckpil/blog/BookStoreWT.java +++ b/write-concise-web-tests-with-selenide/src/test/java/de/rieckpil/blog/BookStoreWT.java @@ -1,5 +1,8 @@ package de.rieckpil.blog; +import static com.codeborne.selenide.Selenide.*; +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment; + import com.codeborne.selenide.CollectionCondition; import com.codeborne.selenide.Condition; import com.codeborne.selenide.Configuration; @@ -11,21 +14,16 @@ import org.openqa.selenium.By; import org.openqa.selenium.chrome.ChromeOptions; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.web.server.LocalServerPort; - -import static com.codeborne.selenide.Selenide.*; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.test.web.server.LocalServerPort; @Disabled("Failing on CI, to be fixed") @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) class BookStoreWT { - @LocalServerPort - private Integer port; + @LocalServerPort private Integer port; @RegisterExtension - static ScreenShooterExtension extension = - new ScreenShooterExtension().to("target/selenide"); + static ScreenShooterExtension extension = new ScreenShooterExtension().to("target/selenide"); @BeforeAll static void configureChromeDriver() { diff --git a/write-concise-web-tests-with-selenide/src/test/java/de/rieckpil/blog/BookStoreYouTubeWT.java b/write-concise-web-tests-with-selenide/src/test/java/de/rieckpil/blog/BookStoreYouTubeWT.java index fdb2c1b2..ffa8ab74 100644 --- a/write-concise-web-tests-with-selenide/src/test/java/de/rieckpil/blog/BookStoreYouTubeWT.java +++ b/write-concise-web-tests-with-selenide/src/test/java/de/rieckpil/blog/BookStoreYouTubeWT.java @@ -1,5 +1,8 @@ package de.rieckpil.blog; +import static com.codeborne.selenide.Selenide.*; +import static org.testcontainers.Testcontainers.exposeHostPorts; + import com.codeborne.selenide.Condition; import com.codeborne.selenide.Configuration; import com.codeborne.selenide.WebDriverRunner; @@ -12,30 +15,32 @@ import org.openqa.selenium.remote.RemoteWebDriver; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.core.env.Environment; import org.testcontainers.containers.BrowserWebDriverContainer; import org.testcontainers.junit.jupiter.Testcontainers; - -import static com.codeborne.selenide.Selenide.*; -import static org.testcontainers.Testcontainers.exposeHostPorts; +import org.testcontainers.utility.DockerImageName; @Testcontainers(disabledWithoutDocker = true) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) class BookStoreYouTubeWT { - @LocalServerPort - private Integer port; + @LocalServerPort private Integer port; - static BrowserWebDriverContainer webDriverContainer = - new BrowserWebDriverContainer<>() - .withCapabilities(new ChromeOptions() - .addArguments("--no-sandbox") - .addArguments("--disable-dev-shm-usage")); + public static BrowserWebDriverContainer webDriverContainer = + new BrowserWebDriverContainer<>( + System.getProperty("os.arch").equals("aarch64") + ? DockerImageName.parse("seleniarm/standalone-chromium") + .asCompatibleSubstituteFor("selenium/standalone-chrome") + : DockerImageName.parse("selenium/standalone-chrome")) + .withCapabilities( + new ChromeOptions() + .addArguments("--no-sandbox") + .addArguments("--disable-dev-shm-usage")); @RegisterExtension static ScreenShooterExtension screenShooterExtension = - new ScreenShooterExtension().to("target/selenide"); + new ScreenShooterExtension().to("target/selenide"); @BeforeAll static void beforeAll(@Autowired Environment environment) {