diff --git a/.gitignore b/.gitignore index 48b52bec06..aeb63f7323 100644 --- a/.gitignore +++ b/.gitignore @@ -99,4 +99,7 @@ spring-boot-modules/spring-boot-react/frontend/yarn.lock spring-boot-modules/spring-boot-properties-3/*.log # SDKMan -.sdkmanrc \ No newline at end of file +.sdkmanrc + +# Localstack +**/.localstack \ No newline at end of file diff --git a/algorithms-modules/algorithms-miscellaneous-4/pom.xml b/algorithms-modules/algorithms-miscellaneous-4/pom.xml index ed752a6b41..0e0841b72e 100644 --- a/algorithms-modules/algorithms-miscellaneous-4/pom.xml +++ b/algorithms-modules/algorithms-miscellaneous-4/pom.xml @@ -13,18 +13,32 @@ 1.0.0-SNAPSHOT - - - com.google.guava - guava - ${guava.version} - - - org.projectlombok - lombok - ${lombok.version} - provided - - + + 3.3.3 + 4.4 + + + + com.google.guava + guava + ${guava.version} + + + org.projectlombok + lombok + ${lombok.version} + provided + + + com.github.dpaukov + combinatoricslib3 + ${combinatoricslib3.version} + + + org.apache.commons + commons-collections4 + ${commons-collections4.version} + + \ No newline at end of file diff --git a/algorithms-modules/algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/stringpermutation/ArrayHelper.java b/algorithms-modules/algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/stringpermutation/ArrayHelper.java new file mode 100644 index 0000000000..6b4f1fcb12 --- /dev/null +++ b/algorithms-modules/algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/stringpermutation/ArrayHelper.java @@ -0,0 +1,14 @@ +package com.baeldung.algorithms.stringpermutation; + +import java.util.List; +import java.util.stream.Collectors; + +public class ArrayHelper { + + private ArrayHelper() { + } + + static List toCharacterList(final String string) { + return string.chars().mapToObj(s -> ((char) s)).collect(Collectors.toList()); + } +} diff --git a/algorithms-modules/algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/stringpermutation/StringPermutationsApache.java b/algorithms-modules/algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/stringpermutation/StringPermutationsApache.java new file mode 100644 index 0000000000..c2522a6ec5 --- /dev/null +++ b/algorithms-modules/algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/stringpermutation/StringPermutationsApache.java @@ -0,0 +1,20 @@ +package com.baeldung.algorithms.stringpermutation; + +import java.util.Collection; +import java.util.List; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.collections4.iterators.PermutationIterator; + +public class StringPermutationsApache { + + public Collection> eagerPermutationWithRepetitions(final String string) { + final List characters = ArrayHelper.toCharacterList(string); + return CollectionUtils.permutations(characters); + } + + public PermutationIterator lazyPermutationWithoutRepetitions(final String string) { + final List characters = ArrayHelper.toCharacterList(string); + return new PermutationIterator<>(characters); + } + +} diff --git a/algorithms-modules/algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/stringpermutation/StringPermutationsCombinatoricsLib.java b/algorithms-modules/algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/stringpermutation/StringPermutationsCombinatoricsLib.java new file mode 100644 index 0000000000..78182f8045 --- /dev/null +++ b/algorithms-modules/algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/stringpermutation/StringPermutationsCombinatoricsLib.java @@ -0,0 +1,26 @@ +package com.baeldung.algorithms.stringpermutation; + +import java.util.List; +import java.util.stream.Collectors; +import org.paukov.combinatorics3.Generator; +import org.paukov.combinatorics3.PermutationGenerator.TreatDuplicatesAs; + +public class StringPermutationsCombinatoricsLib { + + public List> permutationWithoutRepetitions(final String string) { + List chars = ArrayHelper.toCharacterList(string); + return Generator.permutation(chars) + .simple() + .stream() + .collect(Collectors.toList()); + } + + public List> permutationWithRepetitions(final String string) { + List chars = ArrayHelper.toCharacterList(string); + return Generator.permutation(chars) + .simple(TreatDuplicatesAs.IDENTICAL) + .stream() + .collect(Collectors.toList()); + } + +} diff --git a/algorithms-modules/algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/stringpermutation/StringPermutationsGuava.java b/algorithms-modules/algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/stringpermutation/StringPermutationsGuava.java new file mode 100644 index 0000000000..d055381bf1 --- /dev/null +++ b/algorithms-modules/algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/stringpermutation/StringPermutationsGuava.java @@ -0,0 +1,18 @@ +package com.baeldung.algorithms.stringpermutation; + +import com.google.common.collect.Collections2; +import java.util.Collection; +import java.util.List; + +public class StringPermutationsGuava { + + public Collection> permutationWithRepetitions(final String string) { + final List characters = ArrayHelper.toCharacterList(string); + return Collections2.permutations(characters); + } +public Collection> permutationWithoutRepetitions(final String string) { + final List characters = ArrayHelper.toCharacterList(string); + return Collections2.orderedPermutations(characters); +} + +} diff --git a/algorithms-modules/algorithms-miscellaneous-4/src/test/java/com/baeldung/algorithms/stringpermutation/StringPermutationsApacheUnitTest.java b/algorithms-modules/algorithms-miscellaneous-4/src/test/java/com/baeldung/algorithms/stringpermutation/StringPermutationsApacheUnitTest.java new file mode 100644 index 0000000000..d0deb85887 --- /dev/null +++ b/algorithms-modules/algorithms-miscellaneous-4/src/test/java/com/baeldung/algorithms/stringpermutation/StringPermutationsApacheUnitTest.java @@ -0,0 +1,43 @@ +package com.baeldung.algorithms.stringpermutation; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.Collection; +import java.util.List; +import org.apache.commons.collections4.iterators.PermutationIterator; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +class StringPermutationsApacheUnitTest { + + @CsvSource({"abc, 6", + "hello, 120", + "aaaaaa, 720"}) + @DisplayName("Apache permutation for ") + void testPermutationsWithRepetitions(String string, int numberOfPermutations) { + StringPermutationsApache permutationGenerator = new StringPermutationsApache(); + final Collection> permutations = permutationGenerator.eagerPermutationWithRepetitions(string); + final int size = permutations.size(); + assertThat(permutations) + .as("\"%s\" should have %d permutation, but had %d", string, numberOfPermutations, size) + .hasSize(numberOfPermutations); + } + + @ParameterizedTest + @CsvSource({"abc, 6", + "hello, 120", + "aaaaaa, 720"}) + void testPermutationsWithoutRepetitions(String string, int numberOfPermutations) { + StringPermutationsApache permutationGenerator = new StringPermutationsApache(); + final PermutationIterator permutations = permutationGenerator.lazyPermutationWithoutRepetitions(string); + int size = 0; + while (permutations.hasNext()) { + permutations.next(); + ++size; + } + assertThat(size) + .as("\"%s\" should have %d permutation, but had %d", string, numberOfPermutations, size) + .isEqualTo(numberOfPermutations); + } +} \ No newline at end of file diff --git a/algorithms-modules/algorithms-miscellaneous-4/src/test/java/com/baeldung/algorithms/stringpermutation/StringPermutationsCombinatoricsLibUnitTest.java b/algorithms-modules/algorithms-miscellaneous-4/src/test/java/com/baeldung/algorithms/stringpermutation/StringPermutationsCombinatoricsLibUnitTest.java new file mode 100644 index 0000000000..faca3d8f30 --- /dev/null +++ b/algorithms-modules/algorithms-miscellaneous-4/src/test/java/com/baeldung/algorithms/stringpermutation/StringPermutationsCombinatoricsLibUnitTest.java @@ -0,0 +1,36 @@ +package com.baeldung.algorithms.stringpermutation; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.List; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +class StringPermutationsCombinatoricsLibUnitTest { + + @ParameterizedTest + @CsvSource({"abc, 6", + "hello, 120", + "aaaaaa, 720"}) + void testPermutationsWithRepetitions(String string, int numberOfPermutations) { + StringPermutationsCombinatoricsLib permutationGenerator = new StringPermutationsCombinatoricsLib(); + final List> permutations = permutationGenerator.permutationWithRepetitions(string); + final int size = permutations.size(); + assertThat(permutations) + .as("\"%s\" should have %d permutation, but had %d", string, numberOfPermutations, size) + .hasSize(numberOfPermutations); + } + + @ParameterizedTest + @CsvSource({"abc, 6", + "hello, 60", + "aaaaaa, 1"}) + void testPermutationsWithoutRepetitions(String string, int numberOfPermutations) { + StringPermutationsCombinatoricsLib permutationGenerator = new StringPermutationsCombinatoricsLib(); + final List> permutations = permutationGenerator.permutationWithoutRepetitions(string); + final int size = permutations.size(); + assertThat(permutations) + .as("\"%s\" should have %d permutation, but had %d", string, numberOfPermutations, size) + .hasSize(numberOfPermutations); + } +} \ No newline at end of file diff --git a/algorithms-modules/algorithms-miscellaneous-4/src/test/java/com/baeldung/algorithms/stringpermutation/StringPermutationsGuavaUnitTest.java b/algorithms-modules/algorithms-miscellaneous-4/src/test/java/com/baeldung/algorithms/stringpermutation/StringPermutationsGuavaUnitTest.java new file mode 100644 index 0000000000..d2da100997 --- /dev/null +++ b/algorithms-modules/algorithms-miscellaneous-4/src/test/java/com/baeldung/algorithms/stringpermutation/StringPermutationsGuavaUnitTest.java @@ -0,0 +1,38 @@ +package com.baeldung.algorithms.stringpermutation; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.Collection; +import java.util.List; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +class StringPermutationsGuavaUnitTest { + + @ParameterizedTest + @CsvSource({"abc, 6", + "hello, 120", + "aaaaaa, 720"}) + void testPermutationsWithRepetitions(String string, int numberOfPermutations) { + StringPermutationsGuava permutationGenerator = new StringPermutationsGuava(); + final Collection> permutations = permutationGenerator.permutationWithRepetitions(string); + final int size = permutations.size(); + assertThat(permutations) + .as("\"%s\" should have %d permutation, but had %d", string, numberOfPermutations, size) + .hasSize(numberOfPermutations); + } + + @ParameterizedTest + @CsvSource({"abc, 6", + "hello, 60", + "aaaaaa, 1"}) + void testPermutationsWithoutRepetitions(String string, int numberOfPermutations) { + StringPermutationsGuava permutationGenerator = new StringPermutationsGuava(); + final Collection> permutations = permutationGenerator.permutationWithoutRepetitions(string); + final int size = permutations.size(); + assertThat(permutations) + .as("\"%s\" should have %d permutation, but had %d", string, numberOfPermutations, size) + .hasSize(numberOfPermutations); + } + +} \ No newline at end of file diff --git a/core-java-modules/core-java-collections-list-4/README.md b/core-java-modules/core-java-collections-list-4/README.md index 4c020969e3..34b680e7dc 100644 --- a/core-java-modules/core-java-collections-list-4/README.md +++ b/core-java-modules/core-java-collections-list-4/README.md @@ -6,4 +6,6 @@ This module contains articles about the Java List collection - [Working With a List of Lists in Java](https://www.baeldung.com/java-list-of-lists) - [Reverse an ArrayList in Java](https://www.baeldung.com/java-reverse-arraylist) - [Sort a List Alphabetically in Java](https://www.baeldung.com/java-sort-list-alphabetically) +- [Arrays.asList() vs Collections.singletonList()](https://www.baeldung.com/java-aslist-vs-singletonlist) +- [Replace Element at a Specific Index in a Java ArrayList](https://www.baeldung.com/java-arraylist-replace-at-index) - [[<-- Prev]](/core-java-modules/core-java-collections-list-3) diff --git a/core-java-modules/core-java-collections-maps-5/README.md b/core-java-modules/core-java-collections-maps-5/README.md index 24fb1b56d8..a131c669c6 100644 --- a/core-java-modules/core-java-collections-maps-5/README.md +++ b/core-java-modules/core-java-collections-maps-5/README.md @@ -8,4 +8,5 @@ - [Java Map – keySet() vs. entrySet() vs. values() Methods](https://www.baeldung.com/java-map-entries-methods) - [Java IdentityHashMap Class and Its Use Cases](https://www.baeldung.com/java-identityhashmap) - [How to Invert a Map in Java](https://www.baeldung.com/java-invert-map) +- [Implementing a Map with Multiple Keys in Java](https://www.baeldung.com/java-multiple-keys-map) - More articles: [[<-- prev]](../core-java-collections-maps-4) diff --git a/core-java-modules/core-java-concurrency-advanced-4/README.md b/core-java-modules/core-java-concurrency-advanced-4/README.md index d9207644b3..b9881fd475 100644 --- a/core-java-modules/core-java-concurrency-advanced-4/README.md +++ b/core-java-modules/core-java-concurrency-advanced-4/README.md @@ -7,3 +7,4 @@ - [Producer-Consumer Problem With Example in Java](https://www.baeldung.com/java-producer-consumer-problem) - [Acquire a Lock by a Key in Java](https://www.baeldung.com/java-acquire-lock-by-key) - [Differences Between set() and lazySet() in Java Atomic Variables](https://www.baeldung.com/java-atomic-set-vs-lazyset) +- [Volatile vs. Atomic Variables in Java](https://www.baeldung.com/java-volatile-vs-atomic) diff --git a/core-java-modules/core-java-exceptions-4/README.md b/core-java-modules/core-java-exceptions-4/README.md index 1ea95510e9..ccc40f3858 100644 --- a/core-java-modules/core-java-exceptions-4/README.md +++ b/core-java-modules/core-java-exceptions-4/README.md @@ -7,4 +7,5 @@ This module contains articles about core java exceptions - [Java Missing Return Statement](https://www.baeldung.com/java-missing-return-statement) - [Convert long to int Type in Java](https://www.baeldung.com/java-convert-long-to-int) - [“Sneaky Throws” in Java](https://www.baeldung.com/java-sneaky-throws) -- [[<-- Prev]](../core-java-exceptions-3) \ No newline at end of file +- [Get the Current Stack Trace in Java](https://www.baeldung.com/java-get-current-stack-trace) +- [[<-- Prev]](../core-java-exceptions-3) diff --git a/core-java-modules/core-java-lang-oop-constructors/README.md b/core-java-modules/core-java-lang-oop-constructors/README.md index ddd0ec6afb..a552a79721 100644 --- a/core-java-modules/core-java-lang-oop-constructors/README.md +++ b/core-java-modules/core-java-lang-oop-constructors/README.md @@ -11,3 +11,4 @@ This module contains article about constructors in Java - [Constructors in Java Abstract Classes](https://www.baeldung.com/java-abstract-classes-constructors) - [Java Implicit Super Constructor is Undefined Error](https://www.baeldung.com/java-implicit-super-constructor-is-undefined-error) - [Constructor Specification in Java](https://www.baeldung.com/java-constructor-specification) +- [Static vs. Instance Initializer Block in Java](https://www.baeldung.com/java-static-instance-initializer-blocks) diff --git a/core-java-modules/core-java-networking-2/src/test/java/com/baeldung/download/FileDownloadIntegrationTest.java b/core-java-modules/core-java-networking-2/src/test/java/com/baeldung/download/FileDownloadIntegrationTest.java index 0aba09a539..8fe50efd69 100644 --- a/core-java-modules/core-java-networking-2/src/test/java/com/baeldung/download/FileDownloadIntegrationTest.java +++ b/core-java-modules/core-java-networking-2/src/test/java/com/baeldung/download/FileDownloadIntegrationTest.java @@ -17,9 +17,9 @@ import static org.junit.Assert.assertTrue; public class FileDownloadIntegrationTest { - static String FILE_URL = "https://s3.amazonaws.com/baeldung.com/Do+JSON+with+Jackson+by+Baeldung.pdf"; + static String FILE_URL = "https://s3.amazonaws.com/baeldung.com/Do+JSON+with+Jackson.pdf?__s=vatuzcrazsqopnn7finb"; static String FILE_NAME = "file.dat"; - static String FILE_MD5_HASH = "753197aa27f162faa3e3c2e48ee5eb07"; + static String FILE_MD5_HASH = "CE20E17B1E1FBF65A85E74AC00FA1FD8"; @Test public void givenJavaIO_whenDownloadingFile_thenDownloadShouldBeCorrect() throws NoSuchAlgorithmException, IOException { diff --git a/core-java-modules/core-java-numbers-5/README.md b/core-java-modules/core-java-numbers-5/README.md index dd80febce9..d7e37d0ee7 100644 --- a/core-java-modules/core-java-numbers-5/README.md +++ b/core-java-modules/core-java-numbers-5/README.md @@ -1,2 +1,3 @@ ### Relevant Articles: - [Check if a Number Is Odd or Even](https://www.baeldung.com/java-check-number-parity) +- [How to Check Whether an Integer Exists in a Range with Java](https://www.baeldung.com/java-interval-contains-integer) diff --git a/core-java-modules/core-java-streams-4/README.md b/core-java-modules/core-java-streams-4/README.md index 86b293566a..80e4534b0f 100644 --- a/core-java-modules/core-java-streams-4/README.md +++ b/core-java-modules/core-java-streams-4/README.md @@ -2,3 +2,4 @@ - [Count Occurrences Using Java groupingBy Collector](https://www.baeldung.com/java-groupingby-count) - [How to Split a Stream into Multiple Streams](https://www.baeldung.com/java-split-stream) +- [Filter Java Stream to 1 and Only 1 Element](https://www.baeldung.com/java-filter-stream-unique-element) diff --git a/core-java-modules/core-java-string-conversions-2/src/test/java/com/baeldung/inttostring/IntToStringUnitTest.java b/core-java-modules/core-java-string-conversions-2/src/test/java/com/baeldung/inttostring/IntToStringUnitTest.java new file mode 100644 index 0000000000..b865d0933d --- /dev/null +++ b/core-java-modules/core-java-string-conversions-2/src/test/java/com/baeldung/inttostring/IntToStringUnitTest.java @@ -0,0 +1,29 @@ +package com.baeldung.chararraytostring; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +public class IntToStringUnitTest { + + @Test + public void whenValidIntIsPassed_thenShouldConvertToString() { + assertEquals("11", Integer.toString(11)); + assertEquals("11", Integer.toString(+11)); + assertEquals("-11", Integer.toString(-11)); + } + + @Test + public void whenValidIntIsPassed_thenShouldConvertToValidString() { + assertEquals("11", String.valueOf(11)); + assertEquals("11", String.valueOf(+11)); + assertEquals("-11", String.valueOf(-11)); + } + + @Test(expected = NullPointerException.class) + public void whenNullIntegerObjectIsPassed_thenShouldThrowException() { + Integer i = null; + System.out.println(String.valueOf(i)); // it prints "null" + System.out.println(i.toString()); + } +} diff --git a/core-java-modules/core-java-string-operations-4/src/main/java/com/baeldung/namedformatting/NamedFormatter.java b/core-java-modules/core-java-string-operations-4/src/main/java/com/baeldung/namedformatting/NamedFormatter.java new file mode 100644 index 0000000000..0fd0642f0e --- /dev/null +++ b/core-java-modules/core-java-string-operations-4/src/main/java/com/baeldung/namedformatting/NamedFormatter.java @@ -0,0 +1,31 @@ +package com.baeldung.namedformatting; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class NamedFormatter { + private NamedFormatter() {} + + public static String format(String template, Map parameters) { + StringBuilder newTemplate = new StringBuilder(template); + List valueList = new ArrayList<>(); + + Matcher matcher = Pattern.compile("[$][{](\\w+)}").matcher(template); + + while (matcher.find()) { + String key = matcher.group(1); + + String paramName = "${" + key + "}"; + int index = newTemplate.indexOf(paramName); + if (index != -1) { + newTemplate.replace(index, index + paramName.length(), "%s"); + valueList.add(parameters.get(key)); + } + } + + return String.format(newTemplate.toString(), valueList.toArray()); + } +} diff --git a/core-java-modules/core-java-string-operations-4/src/test/java/com/baeldung/namedformatting/NamedFormatterUnitTest.java b/core-java-modules/core-java-string-operations-4/src/test/java/com/baeldung/namedformatting/NamedFormatterUnitTest.java new file mode 100644 index 0000000000..843aaac0b5 --- /dev/null +++ b/core-java-modules/core-java-string-operations-4/src/test/java/com/baeldung/namedformatting/NamedFormatterUnitTest.java @@ -0,0 +1,47 @@ +package com.baeldung.namedformatting; + +import org.apache.commons.text.StrSubstitutor; +import org.junit.jupiter.api.Test; + +import java.util.HashMap; +import java.util.Map; + +import static org.assertj.core.api.Assertions.assertThat; + +class NamedFormatterUnitTest { + private static final String TEMPLATE = "Text: [${text}] Number: [${number}] Text again: [${text}]"; + + @Test + void givenTemplateWithNamedParam_whenCallingCommonsTextStrSubstitutor_shouldGetExpectedResult() { + Map params = new HashMap<>(); + params.put("text", "It's awesome!"); + params.put("number", 42); + String result = StrSubstitutor.replace(TEMPLATE, params, "${", "}"); + assertThat(result).isEqualTo("Text: [It's awesome!] Number: [42] Text again: [It's awesome!]"); + } + + @Test + void givenTemplateWithNamedParam_whenCallingCommonsTextStrSubstitutorWithParameterNames_shouldNotWorkAsExpected() { + Map params = new HashMap<>(); + params.put("text", "'${number}' is a placeholder."); + params.put("number", 42); + String result = StrSubstitutor.replace(TEMPLATE, params, "${", "}"); + + assertThat(result).isNotEqualTo("Text: ['${number}' is a placeholder.] Number: [42] Text again: ['${number}' is a placeholder.]"); + + assertThat(result).isEqualTo("Text: ['42' is a placeholder.] Number: [42] Text again: ['42' is a placeholder.]"); + } + + @Test + void givenTemplateWithNamedParam_whenCallingNamedFormatter_shouldGetExpectedResult() { + Map params = new HashMap<>(); + params.put("text", "It's awesome!"); + params.put("number", 42); + String result = NamedFormatter.format(TEMPLATE, params); + assertThat(result).isEqualTo("Text: [It's awesome!] Number: [42] Text again: [It's awesome!]"); + + params.put("text", "'${number}' is a placeholder."); + result = NamedFormatter.format(TEMPLATE, params); + assertThat(result).isEqualTo("Text: ['${number}' is a placeholder.] Number: [42] Text again: ['${number}' is a placeholder.]"); + } +} diff --git a/docker-modules/docker-compose/multiple-mounts/bind_mount_and_volume.yml b/docker-modules/docker-compose/multiple-mounts/bind_mount_and_volume.yml new file mode 100644 index 0000000000..1a8ea2dc25 --- /dev/null +++ b/docker-modules/docker-compose/multiple-mounts/bind_mount_and_volume.yml @@ -0,0 +1,15 @@ +services: + mysql-db: + image: mysql:latest + environment: + - MYSQL_ROOT_PASSWORD=password + - MYSQL_ROOT_HOST=localhost + ports: + - '3306:3306' + volumes: + - first-volume-data:/var/lib/mysql + - ./init.sql:/docker-entrypoint-initdb.d/init.sql + +volumes: + first-volume-data: + external: true \ No newline at end of file diff --git a/docker-modules/docker-compose/multiple-mounts/init.sql b/docker-modules/docker-compose/multiple-mounts/init.sql new file mode 100644 index 0000000000..345a9914fb --- /dev/null +++ b/docker-modules/docker-compose/multiple-mounts/init.sql @@ -0,0 +1,9 @@ +CREATE DATABASE IF NOT EXISTS test; + +use test; + +CREATE TABLE IF NOT EXISTS test_table (id int, description varchar(255)); + +INSERT INTO test_table VALUES (1, 'TEST_1'); +INSERT INTO test_table VALUES (2, 'TEST_2'); +INSERT INTO test_table VALUES (3, 'TEST_3'); \ No newline at end of file diff --git a/docker-modules/docker-compose/multiple-mounts/multiple_bind_mounts.yml b/docker-modules/docker-compose/multiple-mounts/multiple_bind_mounts.yml new file mode 100644 index 0000000000..98c0275583 --- /dev/null +++ b/docker-modules/docker-compose/multiple-mounts/multiple_bind_mounts.yml @@ -0,0 +1,15 @@ +services: + localstack: + privileged: true + image: localstack/localstack:latest + container_name: localstack + ports: + - '4563-4599:4563-4599' + - '8055:8080' + environment: + - SERVICES=s3 + - DEBUG=1 + - DATA_DIR=/tmp/localstack/data + volumes: + - './.localstack:/var/lib/localstack' + - '/var/run/docker.sock:/var/run/docker.sock' \ No newline at end of file diff --git a/docker-modules/docker-compose/multiple-mounts/multiple_volumes.yaml b/docker-modules/docker-compose/multiple-mounts/multiple_volumes.yaml new file mode 100644 index 0000000000..bd722ac5b5 --- /dev/null +++ b/docker-modules/docker-compose/multiple-mounts/multiple_volumes.yaml @@ -0,0 +1,15 @@ +services: + my_app: + image: web-app:latest + container_name: web-app + ports: + - "8080:8080" + volumes: + - first-volume-data:/container-path-1 + - second-volume-data:/container-path-2:ro + +volumes: + first-volume-data: + driver: local + second-volume-data: + driver: local \ No newline at end of file diff --git a/docker-modules/docker-java-jar/README.md b/docker-modules/docker-java-jar/README.md new file mode 100644 index 0000000000..73c8249e58 --- /dev/null +++ b/docker-modules/docker-java-jar/README.md @@ -0,0 +1,4 @@ + +### Relevant Articles: + +- [Dockerizing a Java Application](https://www.baeldung.com/java-dockerize-app) diff --git a/performance-tests/pom.xml b/performance-tests/pom.xml index 8d402865ef..542a505b16 100644 --- a/performance-tests/pom.xml +++ b/performance-tests/pom.xml @@ -150,9 +150,9 @@ 1.5.4 - 6.5.0 - 1.3.1.Final - 2.3.8 + 6.5.2 + 1.5.2.Final + 3.1.0 1.6.1.CR2 1.8 diff --git a/spring-5-reactive-modules/spring-reactive/src/main/java/com/baeldung/reactive/webclient/WebClientController.java b/spring-5-reactive-modules/spring-reactive/src/main/java/com/baeldung/reactive/webclient/WebClientController.java index 0a83b1a1b7..d0d56f7f1b 100644 --- a/spring-5-reactive-modules/spring-reactive/src/main/java/com/baeldung/reactive/webclient/WebClientController.java +++ b/spring-5-reactive-modules/spring-reactive/src/main/java/com/baeldung/reactive/webclient/WebClientController.java @@ -29,6 +29,11 @@ public class WebClientController { return bodyString.map(body -> "processed-" + body); } + @PostMapping("/resource-override") + public Mono postStringResourceOverride(@RequestBody Mono bodyString) { + return bodyString.map(body -> "override-processed-" + body); + } + @PostMapping("/resource-foo") public Mono postFooResource(@RequestBody Mono bodyFoo) { return bodyFoo.map(foo -> "processedFoo-" + foo.getName()); diff --git a/spring-5-reactive-modules/spring-reactive/src/test/java/com/baeldung/reactive/webclient/WebClientIntegrationTest.java b/spring-5-reactive-modules/spring-reactive/src/test/java/com/baeldung/reactive/webclient/WebClientIntegrationTest.java index 5f42610c3d..aaecb6498c 100644 --- a/spring-5-reactive-modules/spring-reactive/src/test/java/com/baeldung/reactive/webclient/WebClientIntegrationTest.java +++ b/spring-5-reactive-modules/spring-reactive/src/test/java/com/baeldung/reactive/webclient/WebClientIntegrationTest.java @@ -54,58 +54,44 @@ class WebClientIntegrationTest { @Test void givenDifferentWebClientCreationMethods_whenUsed_thenObtainExpectedResponse() { - // WebClient creation - WebClient client1 = WebClient.create(); - WebClient client2 = WebClient.create("http://localhost:" + port); - WebClient client3 = WebClient.builder() - .baseUrl("http://localhost:" + port) - .defaultCookie("cookieKey", "cookieValue") - .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) - .defaultUriVariables(Collections.singletonMap("url", "http://localhost:8080")) - .build(); - - // response assertions + WebClient client1 = WebClient.builder().clientConnector(httpConnector()).build(); StepVerifier.create(retrieveResponse(client1.post() .uri("http://localhost:" + port + "/resource"))) .expectNext("processed-bodyValue") .verifyComplete(); + + WebClient client2 = WebClient.builder().baseUrl("http://localhost:" + port) + .clientConnector(httpConnector()).build(); StepVerifier.create(retrieveResponse(client2)) .expectNext("processed-bodyValue") .verifyComplete(); + + WebClient client3 = WebClient.builder() + .baseUrl("http://localhost:" + port) + .clientConnector(httpConnector()) + .defaultCookie("cookieKey", "cookieValue") + .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) + .defaultUriVariables(Collections.singletonMap("url", "http://localhost:8080")) + .build(); StepVerifier.create(retrieveResponse(client3)) .expectNext("processed-bodyValue") .verifyComplete(); - // assert response without specifying URI - StepVerifier.create(retrieveResponse(client1)) - .expectErrorMatches(ex -> WebClientRequestException.class.isAssignableFrom(ex.getClass()) && ex.getMessage() - .contains("Connection refused")) - .verify(); - } - - @Test - void givenWebClientCreationWithoutUri_whenUsed_thenObtainExpectedResponse() { - WebClient client = WebClient.create(); - - StepVerifier.create(retrieveResponse(client)) - .expectErrorMatches(ex -> WebClientRequestException.class.isAssignableFrom(ex.getClass()) && ex.getMessage() - .contains("Connection refused")) - .verify(); } @Test void givenDifferentMethodSpecifications_whenUsed_thenObtainExpectedResponse() { - // request specification - RequestBodyUriSpec uriSpecPost1 = createDefaultClient().method(HttpMethod.POST); - RequestBodyUriSpec uriSpecPost2 = createDefaultClient().post(); - RequestHeadersUriSpec requestGet = createDefaultClient().get(); - // response assertions + RequestBodyUriSpec uriSpecPost1 = createDefaultClient().method(HttpMethod.POST); StepVerifier.create(retrieveResponse(uriSpecPost1)) .expectNext("processed-bodyValue") .verifyComplete(); + + RequestBodyUriSpec uriSpecPost2 = createDefaultClient().post(); StepVerifier.create(retrieveResponse(uriSpecPost2)) .expectNext("processed-bodyValue") .verifyComplete(); + + RequestHeadersUriSpec requestGet = createDefaultClient().get(); StepVerifier.create(retrieveGetResponse(requestGet)) .expectNextMatches(nextMap -> nextMap.get("field") .equals("value")) @@ -114,21 +100,21 @@ class WebClientIntegrationTest { @Test void givenDifferentUriSpecifications_whenUsed_thenObtainExpectedResponse() { - // uri specification - RequestBodySpec bodySpecUsingString = createDefaultPostRequest().uri("/resource"); - RequestBodySpec bodySpecUsingUriBuilder = createDefaultPostRequest().uri( - uriBuilder -> uriBuilder.pathSegment("resource") - .build()); - RequestBodySpec bodySpecusingURI = createDefaultPostRequest().uri( - URI.create("http://localhost:" + port + "/resource")); - // response assertions + RequestBodySpec bodySpecUsingString = createDefaultPostRequest().uri("/resource"); StepVerifier.create(retrieveResponse(bodySpecUsingString)) .expectNext("processed-bodyValue") .verifyComplete(); + + RequestBodySpec bodySpecUsingUriBuilder = createDefaultPostRequest().uri( + uriBuilder -> uriBuilder.pathSegment("resource") + .build()); StepVerifier.create(retrieveResponse(bodySpecUsingUriBuilder)) .expectNext("processed-bodyValue") .verifyComplete(); + + RequestBodySpec bodySpecusingURI = createDefaultPostRequest().uri( + URI.create("http://localhost:" + port + "/resource")); StepVerifier.create(retrieveResponse(bodySpecusingURI)) .expectNext("processed-bodyValue") .verifyComplete(); @@ -136,21 +122,23 @@ class WebClientIntegrationTest { @Test void givenOverriddenUriSpecifications_whenUsed_thenObtainExpectedResponse() { - RequestBodySpec bodySpecOverriddenBaseUri = createDefaultPostRequest().uri(URI.create("/resource")); + RequestBodySpec bodySpecOverriddenBaseUri = createDefaultPostRequest() + .uri(URI.create("http://localhost:" + port + "/resource-override")); + StepVerifier.create(retrieveResponse(bodySpecOverriddenBaseUri)) - .expectErrorMatches(ex -> WebClientRequestException.class.isAssignableFrom(ex.getClass()) && ex.getMessage() - .contains("Connection refused")) - .verify(); + .expectNext("override-processed-bodyValue") + .verifyComplete(); RequestBodySpec bodySpecOverriddenBaseUri2 = WebClient.builder() + .clientConnector(httpConnector()) .baseUrl("http://localhost:" + port) .build() .post() - .uri(URI.create("/resource")); + .uri(URI.create("http://localhost:" + port + "/resource-override")); + StepVerifier.create(retrieveResponse(bodySpecOverriddenBaseUri2)) - .expectErrorMatches(ex -> WebClientRequestException.class.isAssignableFrom(ex.getClass()) && ex.getMessage() - .contains("Connection refused")) - .verify(); + .expectNext("override-processed-bodyValue") + .verifyComplete(); } @Test @@ -195,7 +183,7 @@ class WebClientIntegrationTest { StepVerifier.create(retrieveResponse(headersSpecPlainObject)) .expectError(CodecException.class) .verify(); - // assert response for request with no body + // assert response for request without body Mono> responsePostWithNoBody = createDefaultPostResourceRequest().exchangeToMono( responseHandler -> { assertThat(responseHandler.statusCode()).isEqualTo(HttpStatus.BAD_REQUEST); @@ -294,7 +282,17 @@ class WebClientIntegrationTest { // helper methods to create default instances private WebClient createDefaultClient() { - return WebClient.create("http://localhost:" + port); + return WebClient.builder() + .baseUrl("http://localhost:" + port) + .clientConnector(httpConnector()) + .build(); + } + + private static ReactorClientHttpConnector httpConnector() { + HttpClient httpClient = HttpClient + .create() + .wiretap(true); + return new ReactorClientHttpConnector(httpClient); } private RequestBodyUriSpec createDefaultPostRequest() { @@ -315,35 +313,30 @@ class WebClientIntegrationTest { .uri("/resource") .bodyValue(BODY_VALUE) .retrieve() - .bodyToMono(String.class) - .log(); + .bodyToMono(String.class); } private Mono retrieveResponse(RequestBodyUriSpec spec) { return spec.uri("/resource") .bodyValue(BODY_VALUE) .retrieve() - .bodyToMono(String.class) - .log(); + .bodyToMono(String.class); } private Mono> retrieveGetResponse(RequestHeadersUriSpec spec) { return spec.uri("/resource") .retrieve() - .bodyToMono(MAP_RESPONSE_REF) - .log(); + .bodyToMono(MAP_RESPONSE_REF); } private Mono retrieveResponse(RequestBodySpec spec) { return spec.bodyValue(BODY_VALUE) .retrieve() - .bodyToMono(String.class) - .log(); + .bodyToMono(String.class); } private Mono retrieveResponse(RequestHeadersSpec spec) { return spec.retrieve() - .bodyToMono(String.class) - .log(); + .bodyToMono(String.class); } } diff --git a/spring-5-reactive-modules/spring-reactive/src/test/resources/logback-test.xml b/spring-5-reactive-modules/spring-reactive/src/test/resources/logback-test.xml index 69c10177a9..fdc2b300c0 100644 --- a/spring-5-reactive-modules/spring-reactive/src/test/resources/logback-test.xml +++ b/spring-5-reactive-modules/spring-reactive/src/test/resources/logback-test.xml @@ -9,6 +9,9 @@ name="com.baeldung.reactive.debugging.consumer.service.FooService"> + + + diff --git a/spring-boot-modules/spring-boot-3/README.md b/spring-boot-modules/spring-boot-3/README.md new file mode 100644 index 0000000000..25408777b9 --- /dev/null +++ b/spring-boot-modules/spring-boot-3/README.md @@ -0,0 +1,4 @@ + +### Relevant Articles: + +- [Spring Boot 3 and Spring Framework 6.0 – What's New](https://www.baeldung.com/spring-boot-3-spring-6-new) diff --git a/spring-boot-modules/spring-boot-libraries-2/README.md b/spring-boot-modules/spring-boot-libraries-2/README.md index 2031b76661..a516ddbf52 100644 --- a/spring-boot-modules/spring-boot-libraries-2/README.md +++ b/spring-boot-modules/spring-boot-libraries-2/README.md @@ -9,5 +9,6 @@ This module contains articles about various Spring Boot libraries - [An Introduction to Kong](https://www.baeldung.com/kong) - [Getting Started With GraphQL SPQR and Spring Boot](https://www.baeldung.com/spring-boot-graphql-spqr) - [How to Test GraphQL Using Postman](https://www.baeldung.com/graphql-postman) +- [Scanning Java Annotations At Runtime](https://www.baeldung.com/java-scan-annotations-runtime) More articles: [[prev -->]](/spring-boot-modules/spring-boot-libraries) diff --git a/spring-core-6/README.md b/spring-core-6/README.md index e5d425aa74..2fc7ae3899 100644 --- a/spring-core-6/README.md +++ b/spring-core-6/README.md @@ -1,3 +1,4 @@ ### Relevant Articles: - [Instantiating Multiple Beans of the Same Class with Spring Annotations](https://www.baeldung.com/spring-same-class-multiple-beans) +- [Using Environment Variables in Spring Boot's application.properties](https://www.baeldung.com/spring-boot-properties-env-variables) diff --git a/spring-jersey/pom.xml b/spring-jersey/pom.xml index 197469ccf9..674a5a48d6 100644 --- a/spring-jersey/pom.xml +++ b/spring-jersey/pom.xml @@ -100,6 +100,18 @@ jackson-databind ${jackson.version} + + com.fasterxml.jackson.core + jackson-annotations + ${jackson.version} + + + + com.fasterxml.jackson.core + jackson-core + ${jackson.version} + + org.slf4j slf4j-jdk14 @@ -206,7 +218,6 @@ 2.29.1 - 2.11.1 1.6.1 4.4.9 4.5.5 diff --git a/spring-jms/src/test/java/com/baeldung/spring/jms/testing/TestContainersActiveMqIntegrationTest.java b/spring-jms/src/test/java/com/baeldung/spring/jms/testing/TestContainersActiveMqLiveTest.java similarity index 95% rename from spring-jms/src/test/java/com/baeldung/spring/jms/testing/TestContainersActiveMqIntegrationTest.java rename to spring-jms/src/test/java/com/baeldung/spring/jms/testing/TestContainersActiveMqLiveTest.java index d117b90423..0f2b1f52d4 100644 --- a/spring-jms/src/test/java/com/baeldung/spring/jms/testing/TestContainersActiveMqIntegrationTest.java +++ b/spring-jms/src/test/java/com/baeldung/spring/jms/testing/TestContainersActiveMqLiveTest.java @@ -27,11 +27,11 @@ import org.springframework.test.context.junit4.SpringRunner; import org.testcontainers.containers.GenericContainer; import org.testcontainers.utility.DockerImageName; -import com.baeldung.spring.jms.testing.TestContainersActiveMqIntegrationTest.TestConfiguration; +import com.baeldung.spring.jms.testing.TestContainersActiveMqLiveTest.TestConfiguration; @RunWith(SpringRunner.class) @ContextConfiguration(classes = { TestConfiguration.class, MessageSender.class }) -public class TestContainersActiveMqIntegrationTest { +public class TestContainersActiveMqLiveTest { @ClassRule public static GenericContainer activeMqContainer = new GenericContainer<>(DockerImageName.parse("rmohr/activemq:5.14.3")).withExposedPorts(61616); diff --git a/spring-kafka/README.md b/spring-kafka/README.md index 5ff3cb625b..49b19ed448 100644 --- a/spring-kafka/README.md +++ b/spring-kafka/README.md @@ -10,6 +10,7 @@ This module contains articles about Spring with Kafka - [Send Large Messages With Kafka](https://www.baeldung.com/java-kafka-send-large-message) - [Configuring Kafka SSL Using Spring Boot](https://www.baeldung.com/spring-boot-kafka-ssl) - [Kafka Streams With Spring Boot](https://www.baeldung.com/spring-boot-kafka-streams) +- [Get the Number of Messages in an Apache Kafka Topic](https://www.baeldung.com/java-kafka-count-topic-messages) ### Intro diff --git a/spring-security-modules/spring-security-web-boot-4/README.md b/spring-security-modules/spring-security-web-boot-4/README.md index 0856315682..caec447846 100644 --- a/spring-security-modules/spring-security-web-boot-4/README.md +++ b/spring-security-modules/spring-security-web-boot-4/README.md @@ -7,4 +7,5 @@ The "REST With Spring" Classes: http://github.learnspringsecurity.com ### Relevant Articles: +- [Spring Security: Upgrading the Deprecated WebSecurityConfigurerAdapter](https://www.baeldung.com/spring-deprecated-websecurityconfigureradapter) - More articles: [[<-- prev]](/spring-security-modules/spring-security-web-boot-3) diff --git a/spring-security-modules/spring-security-web-thymeleaf/README.md b/spring-security-modules/spring-security-web-thymeleaf/README.md index bb3281fa24..a32861d150 100644 --- a/spring-security-modules/spring-security-web-thymeleaf/README.md +++ b/spring-security-modules/spring-security-web-thymeleaf/README.md @@ -4,4 +4,5 @@ This module contains articles about Spring Security with Thymeleaf. ### Relevant Articles: -- [Spring Security with Thymeleaf](https://www.baeldung.com/spring-security-thymeleaf) \ No newline at end of file +- [Spring Security with Thymeleaf](https://www.baeldung.com/spring-security-thymeleaf) +- [Display Logged-in User's Information in Thymeleaf](https://www.baeldung.com/spring-thymeleaf-user-info) diff --git a/spring-swagger-codegen/spring-openapi-generator-api-client/build.gradle b/spring-swagger-codegen/spring-openapi-generator-api-client/build.gradle index d86deb75b8..595676158b 100644 --- a/spring-swagger-codegen/spring-openapi-generator-api-client/build.gradle +++ b/spring-swagger-codegen/spring-openapi-generator-api-client/build.gradle @@ -96,7 +96,7 @@ if(hasProperty('target') && target == 'android') { ext { swagger_annotations_version = "1.5.22" - jackson_version = "2.10.1" + jackson_version = "2.13.3" jackson_databind_version = "2.10.1" jackson_databind_nullable_version = "0.2.1" spring_web_version = "4.3.9.RELEASE" diff --git a/spring-swagger-codegen/spring-swagger-codegen-api-client/build.gradle b/spring-swagger-codegen/spring-swagger-codegen-api-client/build.gradle index 36716a3436..d1818ba78b 100644 --- a/spring-swagger-codegen/spring-swagger-codegen-api-client/build.gradle +++ b/spring-swagger-codegen/spring-swagger-codegen-api-client/build.gradle @@ -95,7 +95,7 @@ if(hasProperty('target') && target == 'android') { ext { swagger_annotations_version = "1.5.15" - jackson_version = "2.8.9" + jackson_version = "2.13.3" spring_web_version = "4.3.9.RELEASE" jodatime_version = "2.9.9" junit_version = "4.12" diff --git a/spring-web-modules/spring-resttemplate-3/src/test/java/com/baeldung/largefile/LargeFileDownloadIntegrationTest.java b/spring-web-modules/spring-resttemplate-3/src/test/java/com/baeldung/largefile/LargeFileDownloadIntegrationTest.java index 687203d21a..a7246849e8 100644 --- a/spring-web-modules/spring-resttemplate-3/src/test/java/com/baeldung/largefile/LargeFileDownloadIntegrationTest.java +++ b/spring-web-modules/spring-resttemplate-3/src/test/java/com/baeldung/largefile/LargeFileDownloadIntegrationTest.java @@ -14,7 +14,7 @@ import org.springframework.web.client.RestTemplate; public class LargeFileDownloadIntegrationTest { - static String FILE_URL = "https://s3.amazonaws.com/baeldung.com/Do+JSON+with+Jackson+by+Baeldung.pdf"; + static String FILE_URL = "https://s3.amazonaws.com/baeldung.com/Do+JSON+with+Jackson.pdf?__s=vatuzcrazsqopnn7finb"; RestTemplate restTemplate; diff --git a/spring-web-modules/spring-thymeleaf-5/README.md b/spring-web-modules/spring-thymeleaf-5/README.md index 7bbaa8b4db..9c817be0a4 100644 --- a/spring-web-modules/spring-thymeleaf-5/README.md +++ b/spring-web-modules/spring-thymeleaf-5/README.md @@ -7,4 +7,5 @@ This module contains articles about Spring with Thymeleaf - [Changing the Thymeleaf Template Directory in Spring Boot](https://www.baeldung.com/spring-thymeleaf-template-directory) - [How to Create an Executable JAR with Maven](https://www.baeldung.com/executable-jar-with-maven) - [Spring MVC Data and Thymeleaf](https://www.baeldung.com/spring-mvc-thymeleaf-data) +- [Upload Image With Spring Boot and Thymeleaf](https://www.baeldung.com/spring-boot-thymeleaf-image-upload) - [[<-- prev]](/spring-thymeleaf) diff --git a/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/MockFinalsUnitTest.java b/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/MockFinalsUnitTest.java index bb03fca06f..24ab67049f 100644 --- a/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/MockFinalsUnitTest.java +++ b/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/MockFinalsUnitTest.java @@ -1,37 +1,32 @@ package com.baeldung.mockito; -import org.junit.Test; - -import static org.junit.Assert.assertNotEquals; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import com.baeldung.mockito.MyList; +import org.junit.Test; public class MockFinalsUnitTest { - @Test - public void whenMockFinalClassMockWorks() { + @Test + public void whenMockFinalMethodMockWorks() { + + MyList myList = new MyList(); + + MyList mock = mock(MyList.class); + when(mock.finalMethod()).thenReturn(1); + + assertThat(mock.finalMethod()).isNotEqualTo(myList.finalMethod()); + } + + @Test + public void whenMockFinalClassMockWorks() { FinalList finalList = new FinalList(); FinalList mock = mock(FinalList.class); when(mock.size()).thenReturn(2); - assertNotEquals(mock.size(), finalList.size()); - - } - - @Test - public void whenMockFinalMethodMockWorks() { - - MyList myList = new MyList(); - - MyList mock = mock(MyList.class); - when(mock.finalMethod()).thenReturn(1); - - assertNotEquals(mock.finalMethod(), myList.finalMethod()); + assertThat(mock.size()).isNotEqualTo(finalList.size()); } - - - } +} diff --git a/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/argumentcaptor/EmailServiceUnitTest.java b/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/argumentcaptor/EmailServiceUnitTest.java index 5ed7be7d6e..c757a8bfb9 100644 --- a/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/argumentcaptor/EmailServiceUnitTest.java +++ b/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/argumentcaptor/EmailServiceUnitTest.java @@ -1,12 +1,18 @@ package com.baeldung.mockito.argumentcaptor; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.*; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; import org.mockito.junit.MockitoJUnitRunner; -import static org.junit.Assert.*; - @RunWith(MockitoJUnitRunner.class) public class EmailServiceUnitTest { @@ -32,7 +38,7 @@ public class EmailServiceUnitTest { Mockito.verify(platform).deliver(emailCaptor.capture()); Email emailCaptorValue = emailCaptor.getValue(); - assertEquals(Format.TEXT_ONLY, emailCaptorValue.getFormat()); + assertThat(emailCaptorValue.getFormat()).isEqualTo(Format.TEXT_ONLY); } @Test @@ -45,7 +51,7 @@ public class EmailServiceUnitTest { Mockito.verify(platform).deliver(emailCaptor.capture()); Email value = emailCaptor.getValue(); - assertEquals(Format.HTML, value.getFormat()); + assertThat(value.getFormat()).isEqualTo(Format.HTML); } @Test @@ -54,7 +60,7 @@ public class EmailServiceUnitTest { ServiceStatus serviceStatus = emailService.checkServiceStatus(); - assertEquals(ServiceStatus.UP, serviceStatus); + assertThat(serviceStatus).isEqualTo(ServiceStatus.UP); } @Test @@ -63,7 +69,7 @@ public class EmailServiceUnitTest { ServiceStatus serviceStatus = emailService.checkServiceStatus(); - assertEquals(ServiceStatus.DOWN, serviceStatus); + assertThat(serviceStatus).isEqualTo(ServiceStatus.DOWN); } @Test @@ -80,7 +86,7 @@ public class EmailServiceUnitTest { Mockito.when(platform.authenticate(credentialsCaptor.capture())).thenReturn(AuthenticationStatus.AUTHENTICATED); assertTrue(emailService.authenticatedSuccessfully(credentials)); - assertEquals(credentials, credentialsCaptor.getValue()); + assertThat(credentialsCaptor.getValue()).isEqualTo(credentials); } @Test diff --git a/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/spy/MockitoMisusingMockOrSpyUnitTest.java b/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/spy/MockitoMisusingMockOrSpyUnitTest.java new file mode 100644 index 0000000000..b3f470427a --- /dev/null +++ b/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/spy/MockitoMisusingMockOrSpyUnitTest.java @@ -0,0 +1,30 @@ +package com.baeldung.mockito.spy; + +import static org.assertj.core.api.Assertions.assertThatNoException; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Test; +import org.mockito.Mockito; +import org.mockito.exceptions.misusing.NotAMockException; + +public class MockitoMisusingMockOrSpyUnitTest { + + @Test + public void givenNotASpy_whenDoReturn_thenThrowNotAMock() { + List list = new ArrayList(); + + assertThatThrownBy(() -> Mockito.doReturn(100).when(list).size()) + .isInstanceOf(NotAMockException.class) + .hasMessageContaining("Argument passed to when() is not a mock!"); + } + + @Test + public void givenASpy_whenDoReturn_thenNoError() { + final List spyList = Mockito.spy(new ArrayList<>()); + + assertThatNoException().isThrownBy(() -> Mockito.doReturn(100).when(spyList).size()); + } +} diff --git a/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/spy/MockitoMisusingUnitTest.java b/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/spy/MockitoMisusingUnitTest.java deleted file mode 100644 index ea12061fc6..0000000000 --- a/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/spy/MockitoMisusingUnitTest.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.baeldung.mockito.spy; - -import org.junit.After; -import org.junit.Test; -import org.mockito.Mockito; -import org.mockito.exceptions.misusing.NotAMockException; -import org.mockito.internal.progress.ThreadSafeMockingProgress; - -import java.util.ArrayList; -import java.util.List; - -import static org.hamcrest.CoreMatchers.containsString; -import static org.junit.Assert.assertThat; -import static org.junit.jupiter.api.Assertions.fail; - -public class MockitoMisusingUnitTest { - - @After - public void tearDown() { - ThreadSafeMockingProgress.mockingProgress().reset(); - } - - @Test - public void givenNotASpy_whenDoReturn_thenThrowNotAMock() { - try { - List list = new ArrayList(); - - Mockito.doReturn(100, Mockito.withSettings().lenient()) - .when(list) - .size(); - - fail("Should have thrown a NotAMockException because 'list' is not a mock!"); - } catch (NotAMockException e) { - assertThat(e.getMessage(), containsString("Argument passed to when() is not a mock!")); - } - } - -} diff --git a/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/spy/MockitoSpyUnitTest.java b/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/spy/MockitoSpyUnitTest.java index d4696e482b..28ca0c327b 100644 --- a/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/spy/MockitoSpyUnitTest.java +++ b/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/spy/MockitoSpyUnitTest.java @@ -1,22 +1,20 @@ package com.baeldung.mockito.spy; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertEquals; + +import java.util.ArrayList; +import java.util.List; + import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mockito; import org.mockito.Spy; import org.mockito.junit.MockitoJUnitRunner; -import java.util.ArrayList; -import java.util.List; - -import static org.junit.Assert.assertEquals; - @RunWith(MockitoJUnitRunner.class) public class MockitoSpyUnitTest { - @Spy - private List aSpyList = new ArrayList(); - @Test public void whenSpyingOnList_thenCorrect() { final List list = new ArrayList(); @@ -28,9 +26,12 @@ public class MockitoSpyUnitTest { Mockito.verify(spyList).add("one"); Mockito.verify(spyList).add("two"); - assertEquals(2, spyList.size()); + assertThat(spyList).hasSize(2); } + @Spy + private List aSpyList = new ArrayList(); + @Test public void whenUsingTheSpyAnnotation_thenObjectIsSpied() { aSpyList.add("one"); @@ -39,7 +40,7 @@ public class MockitoSpyUnitTest { Mockito.verify(aSpyList).add("one"); Mockito.verify(aSpyList).add("two"); - assertEquals(2, aSpyList.size()); + assertThat(aSpyList).hasSize(2); } @Test @@ -50,7 +51,7 @@ public class MockitoSpyUnitTest { assertEquals(0, spyList.size()); Mockito.doReturn(100).when(spyList).size(); - assertEquals(100, spyList.size()); + assertThat(spyList).hasSize(100); } @Test @@ -60,17 +61,17 @@ public class MockitoSpyUnitTest { mockedList.add("one"); Mockito.verify(mockedList).add("one"); - assertEquals(0, mockedList.size()); + assertThat(mockedList).hasSize(0); } @Test public void whenCreateSpy_thenCreate() { - final List spyList = Mockito.spy(new ArrayList()); + final List spyList = Mockito.spy(new ArrayList<>()); spyList.add("one"); Mockito.verify(spyList).add("one"); - assertEquals(1, spyList.size()); + assertThat(spyList).hasSize(1); } } diff --git a/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/voidmethods/MockitoVoidMethodsUnitTest.java b/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/voidmethods/MockitoVoidMethodsUnitTest.java index 9dd98f184b..dddfaa4c37 100644 --- a/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/voidmethods/MockitoVoidMethodsUnitTest.java +++ b/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/voidmethods/MockitoVoidMethodsUnitTest.java @@ -1,15 +1,23 @@ package com.baeldung.mockito.voidmethods; -import com.baeldung.mockito.MyList; +import static org.junit.Assert.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.isA; +import static org.mockito.ArgumentMatchers.isNull; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.doCallRealMethod; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.junit.MockitoJUnitRunner; -import org.mockito.stubbing.Answer; -import static org.junit.Assert.assertEquals; -import static org.mockito.ArgumentMatchers.*; -import static org.mockito.Mockito.*; +import com.baeldung.mockito.MyList; @RunWith(MockitoJUnitRunner.class) public class MockitoVoidMethodsUnitTest {