Merge remote-tracking branch 'upstream/master'

This commit is contained in:
mcasari 2023-09-19 21:48:22 +02:00
commit 7aeb2821ff
31 changed files with 857 additions and 49 deletions

View File

@ -0,0 +1,49 @@
package com.baeldung.value_based_class;
import java.util.Objects;
import jdk.internal.ValueBased;
/**
* This class is written with the intention that it can serve as an example of
* what a Value-based class could be.
*/
@ValueBased
public final class Point {
private final int x;
private final int y;
private final int z;
private static Point ORIGIN = new Point(0, 0, 0);
private Point(int x, int y, int z) {
this.x = x;
this.y = y;
this.z = z;
}
public static Point valueOfPoint(int x, int y, int z) {
// returns a cached instance if it is origin, or a new instance
if (isOrigin(x, y, z))
return ORIGIN;
return new Point(x, y, z);
}
@Override
public boolean equals(Object other) {
if (other == null || getClass() != other.getClass())
return false;
Point point = (Point) other;
return x == point.x && y == point.y && z == point.z;
}
@Override
public int hashCode() {
return Objects.hash(x, y, z);
}
private static boolean isOrigin(int x, int y, int z) {
return x == 0 && y == 0 && z == 0;
}
}

View File

@ -0,0 +1,41 @@
package com.baeldung.value_based_class;
import org.junit.Assert;
import org.junit.Test;
public class ValueBasedClassUnitTest {
@Test
public void givenAutoboxedAndPrimitive_whenCompared_thenReturnEquals() {
int primitive_a = 125;
Integer obj_a = 125; // this is autoboxed
Assert.assertSame(primitive_a, obj_a);
}
@Test
public void givenValueBasedPoint_whenCreated_thenReturnsObjects() {
Point p1 = Point.valueOfPoint(1, 2, 3);
Point p2 = Point.valueOfPoint(2, 3, 4);
Assert.assertNotEquals(p1, p2);
}
@Test
public void givenValueBasedPoint_whenCompared_thenReturnEquals() {
Point p1 = Point.valueOfPoint(1, 2, 3);
Point p2 = Point.valueOfPoint(1, 2, 3);
Assert.assertEquals(p1, p2);
}
@Test
public void givenValueBasedPoint_whenOrigin_thenReturnCachedInstance() {
Point p1 = Point.valueOfPoint(0, 0, 0);
Point p2 = Point.valueOfPoint(0, 0, 0);
Point p3 = Point.valueOfPoint(1, 2, 3);
// the following should not be assumed for value-based classes
Assert.assertTrue(p1 == p2);
Assert.assertFalse(p1 == p3);
}
}

View File

@ -0,0 +1,26 @@
package com.baeldung.collectionsvsarrays;
import com.baeldung.collectionsvsarrays.sorting.Quicksort;
import java.util.Comparator;
import java.util.List;
public class NonStableSortExample {
public static void main(String[] args) {
List<Task> tasks = Tasks.supplier.get();
Quicksort.sort(tasks, Comparator.comparingInt(Task::getPriority));
System.out.println("After sorting by priority:");
for (Task task : tasks) {
System.out.println(task);
}
Quicksort.sort(tasks, Comparator.comparing(Task::getDueDate));
System.out.println("\nAfter sorting by due date:");
for (Task task : tasks) {
System.out.println(task);
}
}
}

View File

@ -0,0 +1,56 @@
package com.baeldung.collectionsvsarrays;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Warmup;
import org.openjdk.jmh.infra.Blackhole;
@Measurement(iterations = 2, time = 10, timeUnit = TimeUnit.MINUTES)
@Warmup(iterations = 5, time = 10)
@Fork(value = 2)
public class ObjectOverheadBenchmark {
private static final ThreadLocalRandom RANDOM = ThreadLocalRandom.current();
@State(Scope.Benchmark)
public static class Input {
public Supplier<List<Integer>> randomNumbers = () -> RANDOM.ints().limit(10000).boxed().collect(Collectors.toList());
}
@Benchmark
@BenchmarkMode(Mode.Throughput)
public void sortingPrimitiveArray(Input input, Blackhole blackhole) {
final int[] array = input.randomNumbers.get().stream().mapToInt(Integer::intValue).toArray();
Arrays.sort(array);
final List<Integer> result = Arrays.stream(array).boxed().collect(Collectors.toList());
blackhole.consume(result);
}
@Benchmark
@BenchmarkMode(Mode.Throughput)
public void sortingObjectArray(Input input, Blackhole blackhole) {
final Integer[] array = input.randomNumbers.get().toArray(new Integer[0]);
Arrays.sort(array);
blackhole.consume(array);
}
@Benchmark
@BenchmarkMode(Mode.Throughput)
public void sortingObjects(Input input, Blackhole blackhole) {
final List<Integer> list = input.randomNumbers.get();
Collections.sort(list);
blackhole.consume(list);
}
}

View File

@ -0,0 +1,51 @@
package com.baeldung.collectionsvsarrays;
import com.baeldung.collectionsvsarrays.sorting.MergeSort;
import com.baeldung.collectionsvsarrays.sorting.Quicksort;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;
import java.util.stream.IntStream;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.Warmup;
@Measurement(iterations = 2, time = 10, timeUnit = TimeUnit.MINUTES)
@Warmup(iterations = 5, time = 10)
public class PerformanceBenchmark {
private static final Random RANDOM = new Random();
private static final int ARRAY_SIZE = 10000;
private static final int[] randomNumbers = RANDOM.ints(ARRAY_SIZE).toArray();
private static final int[] sameNumbers = IntStream.generate(() -> 42).limit(ARRAY_SIZE).toArray();
public static final Supplier<int[]> randomNumbersSupplier = randomNumbers::clone;
public static final Supplier<int[]> sameNumbersSupplier = sameNumbers::clone;
@Benchmark
@BenchmarkMode(Mode.Throughput)
@Fork(value = 1, jvmArgs = {"-Xlog:gc:file=gc-logs-quick-sort-same-number-%t.txt,filesize=900m -Xmx6gb -Xms6gb"})
public void quickSortSameNumber() {
Quicksort.sort(sameNumbersSupplier.get());
}
@Benchmark
@BenchmarkMode(Mode.Throughput)
@Fork(value = 1, jvmArgs = {"-Xlog:gc:file=gc-logs-quick-sort-random-number-%t.txt,filesize=900m -Xmx6gb -Xms6gb"})
public void quickSortRandomNumber() {
Quicksort.sort(randomNumbersSupplier.get());
}
@Benchmark
@BenchmarkMode(Mode.Throughput)
@Fork(value = 1, jvmArgs = {"-Xlog:gc:file=gc-logs-merge-sort-same-number-%t.txt,filesize=900m -Xmx6gb -Xms6gb"})
public void mergeSortSameNumber() {
MergeSort.sort(sameNumbersSupplier.get());
}
@Benchmark
@BenchmarkMode(Mode.Throughput)
@Fork(value = 1, jvmArgs = {"-Xlog:gc:file=gc-logs-merge-sort-random-number-%t.txt,filesize=900m -Xmx6gb -Xms6gb"})
public void mergeSortRandomNumber() {
MergeSort.sort(randomNumbersSupplier.get());
}
}

View File

@ -0,0 +1,23 @@
package com.baeldung.collectionsvsarrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class StableSortExample {
public static void main(String[] args) {
final List<Task> tasks = Tasks.supplier.get();
Collections.sort(tasks, Comparator.comparingInt(Task::getPriority));
System.out.println("After sorting by priority:");
for (Task task : tasks) {
System.out.println(task);
}
Collections.sort(tasks, Comparator.comparing(Task::getDueDate));
System.out.println("\nAfter sorting by due date:");
for (Task task : tasks) {
System.out.println(task);
}
}
}

View File

@ -0,0 +1,30 @@
package com.baeldung.collectionsvsarrays;
public class Task {
private final long id;
private final int priority;
private final String dueDate;
public Task(final long id, int priority, String dueDate) {
this.id = id;
this.priority = priority;
this.dueDate = dueDate;
}
@Override
public String toString() {
return String.format("Task: #%-2d | Priority: %d | Due Date: %s", getId(), getPriority(), getDueDate());
}
public int getPriority() {
return priority;
}
public String getDueDate() {
return dueDate;
}
private long getId() {
return id;
}
}

View File

@ -0,0 +1,30 @@
package com.baeldung.collectionsvsarrays;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Supplier;
public class Tasks {
private static final List<Task> tasks;
public static final Supplier<List<Task>> supplier;
static {
tasks = new ArrayList<>();
tasks.add(new Task(1, 1, "2023-09-01"));
tasks.add(new Task(2, 2, "2023-08-30"));
tasks.add(new Task(3, 1, "2023-08-29"));
tasks.add(new Task(4, 2, "2023-09-02"));
tasks.add(new Task(5, 3, "2023-09-05"));
tasks.add(new Task(6, 1, "2023-09-03"));
tasks.add(new Task(7, 3, "2023-08-28"));
tasks.add(new Task(8, 2, "2023-09-01"));
tasks.add(new Task(9, 1, "2023-08-28"));
tasks.add(new Task(10, 2, "2023-09-04"));
tasks.add(new Task(11, 3, "2023-08-31"));
tasks.add(new Task(12, 1, "2023-08-30"));
tasks.add(new Task(13, 3, "2023-09-02"));
supplier = () -> new ArrayList<>(tasks);
}
}

View File

@ -0,0 +1,47 @@
package com.baeldung.collectionsvsarrays.sorting;
public class MergeSort {
public static void sort(int[] a) {
sort(a, a.length);
}
public static void sort(int[] a, int n) {
if (n < 2) {
return;
}
int mid = n / 2;
int[] l = new int[mid];
int[] r = new int[n - mid];
for (int i = 0; i < mid; i++) {
l[i] = a[i];
}
for (int i = mid; i < n; i++) {
r[i - mid] = a[i];
}
sort(l, mid);
sort(r, n - mid);
merge(a, l, r, mid, n - mid);
}
private static void merge(
int[] a, int[] l, int[] r, int left, int right) {
int i = 0, j = 0, k = 0;
while (i < left && j < right) {
if (l[i] <= r[j]) {
a[k++] = l[i++];
}
else {
a[k++] = r[j++];
}
}
while (i < left) {
a[k++] = l[i++];
}
while (j < right) {
a[k++] = r[j++];
}
}
}

View File

@ -0,0 +1,72 @@
package com.baeldung.collectionsvsarrays.sorting;
import java.util.Comparator;
import java.util.List;
public class Quicksort {
public static void sort(int arr[]) {
sort(arr, 0, arr.length - 1);
}
public static void sort(int arr[], int begin, int end) {
if (begin < end) {
int partitionIndex = partition(arr, begin, end);
sort(arr, begin, partitionIndex-1);
sort(arr, partitionIndex+1, end);
}
}
private static int partition(int arr[], int begin, int end) {
int pivot = arr[end];
int i = (begin-1);
for (int j = begin; j < end; j++) {
if (arr[j] <= pivot) {
i++;
int swapTemp = arr[i];
arr[i] = arr[j];
arr[j] = swapTemp;
}
}
int swapTemp = arr[i+1];
arr[i+1] = arr[end];
arr[end] = swapTemp;
return i+1;
}
public static <T> void sort(List<T> list, Comparator<T> comparator) {
sort(list, 0, list.size() - 1, comparator);
}
public static <T> void sort(List<T> list, int low, int high, Comparator<T> comparator) {
if (low < high) {
int partitionIndex = partition(list, low, high, comparator);
sort(list, low, partitionIndex - 1, comparator);
sort(list, partitionIndex + 1, high, comparator);
}
}
private static <T> int partition(List<T> list, int begin, int end, Comparator<T> comparator) {
T pivot = list.get(end);
int i = (begin-1);
for (int j = begin; j < end; j++) {
if (comparator.compare(list.get(j), pivot) <= 0) {
i++;
T swapTemp = list.get(i);
list.set(i, list.get(j));
list.set(j, swapTemp);
}
}
T swapTemp = list.get(i+1);
list.set(i+1,list.get(end));
list.set(end, swapTemp);
return i+1;
}
}

View File

@ -0,0 +1,60 @@
package com.baeldung.eofdetections;
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.StandardCharsets;
import java.util.*;
public class EOFDetection {
public String readWithFileInputStream(String pathFile) throws IOException {
try (FileInputStream fis = new FileInputStream(pathFile);
ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
int data;
while ((data = fis.read()) != -1) {
baos.write(data);
}
return baos.toString();
}
}
public String readWithBufferedReader(String pathFile) throws IOException {
try (FileInputStream fis = new FileInputStream(pathFile);
InputStreamReader isr = new InputStreamReader(fis);
BufferedReader reader = new BufferedReader(isr)) {
StringBuilder actualContent = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
actualContent.append(line);
}
return actualContent.toString();
}
}
public String readWithScanner(String pathFile) throws IOException {
File file = new File(pathFile);
Scanner scanner = new Scanner(file);
StringBuilder actualContent = new StringBuilder();
while (scanner.hasNext()) {
String line = scanner.nextLine();
actualContent.append(line);
}
scanner.close();
return actualContent.toString();
}
public String readFileWithFileChannelAndByteBuffer(String pathFile) throws IOException {
try (FileInputStream fis = new FileInputStream(pathFile);
FileChannel channel = fis.getChannel()) {
ByteBuffer buffer = ByteBuffer.allocate((int) channel.size());
while (channel.read(buffer) != -1) {
buffer.flip();
buffer.clear();
}
return StandardCharsets.UTF_8.decode(buffer).toString();
}
}
}

View File

@ -0,0 +1,80 @@
package com.baeldung.eofdetections;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail;
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class EOFDetectionUnitTest {
static final String LOREM_IPSUM = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum";
String pathToFile = "sample.txt"; // init sample file path
EOFDetection eofDetection = new EOFDetection();
@Test
@Order(1)
public void givenDummyText_whenReadWithFileInputStream_returnText() {
try {
String actualText = eofDetection.readWithFileInputStream(pathToFile);
assertEquals(LOREM_IPSUM, actualText);
} catch (IOException e) {
fail(e.getMessage());
}
}
@Test
@Order(2)
public void givenDummyText_whenReadFileWithBufferedReader_returnText() {
try {
String actualText = eofDetection.readWithBufferedReader(pathToFile);
assertEquals(LOREM_IPSUM, actualText);
} catch (IOException e) {
fail(e.getMessage());
}
}
@Test
@Order(3)
public void givenDummyText_whenReadFileWithScanner_returnText() {
try {
String actualText = eofDetection.readWithScanner(pathToFile);
assertEquals(LOREM_IPSUM, actualText);
} catch (IOException e) {
fail(e.getMessage());
}
}
@Test
@Order(4)
public void givenDummyText_whenReadFileWithFileChannelAndByteBuffer_returnText() {
try {
String actualText = eofDetection.readFileWithFileChannelAndByteBuffer(pathToFile);
assertEquals(LOREM_IPSUM, actualText);
} catch (IOException e) {
fail(e.getMessage());
}
}
@Test
@Order(0)
public void prepareFileForTest() {
File file = new File(pathToFile);
if (!file.exists()) {
try {
file.createNewFile();
FileWriter writer = new FileWriter(file);
writer.write(LOREM_IPSUM);
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

View File

@ -23,6 +23,11 @@
<artifactId>commons-lang3</artifactId>
<version>${apache-commons-lang3.version}</version>
</dependency>
<dependency>
<groupId>com.vdurmont</groupId>
<artifactId>emoji-java</artifactId>
<version>${emoji-java.version}</version>
</dependency>
</dependencies>
<build>
@ -52,6 +57,7 @@
<maven.compiler.target>11</maven.compiler.target>
<validator.version>1.7</validator.version>
<apache-commons-lang3.version>3.12.0</apache-commons-lang3.version>
<emoji-java.version>5.1.1</emoji-java.version>
</properties>
</project>

View File

@ -0,0 +1,33 @@
package com.baeldung.findemojis;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import com.vdurmont.emoji.EmojiManager;
public class FindEmojisUnitTest {
@Test
public void givenAWord_whenUsingEmojiJava_thenDetectEmoji() {
boolean emoji = EmojiManager.isEmoji("\uD83D\uDC3B");
assertTrue(emoji);
boolean notEmoji = EmojiManager.isEmoji("w");
assertFalse(notEmoji);
}
@Test
public void givenAWord_whenUsingRegex_thenDetectEmoji() {
String regexPattern = "[\uD800-\uDBFF\uDC00-\uDFFF]+";
String emojiString = "\uD83D\uDC3B";
boolean emoji = emojiString.matches(regexPattern);
assertTrue(emoji);
String notEmojiString = "w";
boolean notEmoji = notEmojiString.matches(regexPattern);
assertFalse(notEmoji);
}
}

View File

@ -1,14 +1,21 @@
plugins{
id "nebula.lint" version "16.9.0"
plugins {
id "nebula.lint" version "18.1.0"
}
description = "Gradle 5 root project"
allprojects {
apply plugin :"java"
apply plugin :"nebula.lint"
apply plugin: "java"
apply plugin: "nebula.lint"
gradleLint {
rules=['unused-dependency']
rules = [
// 'unused-dependency',
// 'dependency-parentheses',
// 'undeclared-dependency',
// 'minimum-dependency-version'
]
reportFormat = 'text'
reportOnlyFixableViolations = true
}
group = "com.baeldung"
version = "0.0.1"
@ -16,6 +23,6 @@ allprojects {
targetCompatibility = "1.8"
repositories {
jcenter()
mavenCentral()
}
}

View File

@ -0,0 +1,6 @@
allprojects {
apply plugin: "nebula.lint"
gradleLint {
rules = ['dependency-parenthesis']
}
}

View File

@ -0,0 +1 @@
/build/

View File

@ -0,0 +1,15 @@
description = "Introduction to Gradle Lint Plugin"
ext {
awsVersion = '2.20.83'
}
dependencies {
implementation platform("software.amazon.awssdk:bom:$awsVersion")
testImplementation('junit:junit:4.13.1')
gradleLint.ignore('unused-dependency', 'dependency-parentheses') {
implementation('software.amazon.awssdk:sts')
}
}

View File

@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip

View File

@ -0,0 +1,16 @@
import com.netflix.nebula.lint.plugin.GradleLintPlugin
initscript {
repositories { mavenCentral() }
dependencies {
classpath 'com.netflix.nebula:gradle-lint-plugin:18.1.0'
}
}
allprojects {
apply plugin: GradleLintPlugin
gradleLint {
rules=[]
alwaysRun= false
}
}

View File

@ -2,4 +2,5 @@ rootProject.name='gradle-5'
include 'java-exec'
include 'unused-dependencies'
include 'source-sets'
include 'cmd-line-args'
include 'cmd-line-args'
include 'gradle-lint-intro'

View File

@ -8,31 +8,19 @@
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-spring-5</artifactId>
<artifactId>parent-boot-2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../../parent-spring-5</relativePath>
<relativePath>../../parent-boot-2</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>${org.springframework.data.version}</version>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver-sync</artifactId>
<version>${mongodb-driver.version}</version>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver-reactivestreams</artifactId>
<version>${mongodb-reactivestreams.version}</version>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-core</artifactId>
<version>${projectreactor.version}</version>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
@ -40,23 +28,6 @@
<version>${projectreactor.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
<exclusions>
<exclusion>
<artifactId>commons-logging</artifactId>
<groupId>commons-logging</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-mongodb</artifactId>
@ -103,12 +74,9 @@
</build>
<properties>
<org.springframework.data.version>3.4.7</org.springframework.data.version>
<querydsl.version>5.0.0</querydsl.version>
<mysema.maven.version>1.1.3</mysema.maven.version>
<mongodb-reactivestreams.version>4.1.0</mongodb-reactivestreams.version>
<projectreactor.version>3.5.4</projectreactor.version>
<mongodb-driver.version>4.6.1</mongodb-driver.version>
<embed.mongo.version>4.6.3</embed.mongo.version>
</properties>

View File

@ -28,6 +28,7 @@ import com.baeldung.model.User;
*
* This test requires:
* * mongodb instance running on the environment
* Run the src/live-test/resources/live-test-setup.sh
*
*/
@RunWith(SpringJUnit4ClassRunner.class)

View File

@ -26,6 +26,7 @@ import com.baeldung.repository.UserRepository;
*
* This test requires:
* * mongodb instance running on the environment
* Run the src/live-test/resources/live-test-setup.sh
*
*/
@RunWith(SpringJUnit4ClassRunner.class)

View File

@ -9,10 +9,11 @@
<name>spring-boot-aws</name>
<description>spring-boot-aws</description>
<!-- "sam build" needs all the dependencies including its parent project. Hence, we cannot use parent-boot in this case -->
<parent>
<groupId>com.baeldung.spring-boot-modules</groupId>
<artifactId>spring-boot-modules</artifactId>
<version>1.0.0-SNAPSHOT</version>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.11</version>
</parent>
<dependencies>

View File

@ -0,0 +1,23 @@
package com.baeldung.construction;
public class CoffeeMachine {
private Grinder grinder;
private WaterTank tank;
public CoffeeMachine() {
this.grinder = new Grinder();
this.tank = new WaterTank();
}
public CoffeeMachine(int mils) {
this.grinder = new Grinder();
this.tank = new WaterTank(mils);
}
public String makeCoffee() {
String type = this.tank.isEspresso() ? "Espresso" : "Americano";
return String.format("Finished making a delicious %s made with %s beans", type, this.grinder.getBeans());
}
}

View File

@ -0,0 +1,12 @@
package com.baeldung.construction;
public class Fruit {
public String getName() {
return "Apple";
}
public String getColour() {
return "Red";
}
}

View File

@ -0,0 +1,19 @@
package com.baeldung.construction;
public class Grinder {
private String beans;
public Grinder() {
this.beans = "Guatemalan";
}
public String getBeans() {
return beans;
}
public void setBeans(String beans) {
this.beans = beans;
}
}

View File

@ -0,0 +1,27 @@
package com.baeldung.construction;
public class WaterTank {
private int mils;
public WaterTank() {
this.mils = 25;
}
public WaterTank(int mils) {
this.mils = mils;
}
public int getMils() {
return mils;
}
public void setMils(int mils) {
this.mils = mils;
}
public boolean isEspresso() {
return getMils() < 50;
}
}

View File

@ -0,0 +1,56 @@
package com.baeldung.construction;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.mockConstruction;
import static org.mockito.Mockito.when;
import org.junit.jupiter.api.Test;
import org.mockito.MockedConstruction;
class CoffeeMachineUnitTest {
@Test
void givenNoMockedContructor_whenCoffeeMade_thenRealDependencyReturned() {
CoffeeMachine machine = new CoffeeMachine();
assertEquals("Finished making a delicious Espresso made with Guatemalan beans", machine.makeCoffee());
}
@Test
void givenMockedContructor_whenCoffeeMade_thenMockDependencyReturned() {
try (MockedConstruction<WaterTank> mockTank = mockConstruction(WaterTank.class); MockedConstruction<Grinder> mockGrinder = mockConstruction(Grinder.class)) {
CoffeeMachine machine = new CoffeeMachine();
WaterTank tank = mockTank.constructed()
.get(0);
Grinder grinder = mockGrinder.constructed()
.get(0);
when(tank.isEspresso()).thenReturn(false);
when(grinder.getBeans()).thenReturn("Peruvian");
assertEquals("Finished making a delicious Americano made with Peruvian beans", machine.makeCoffee());
}
}
@Test
void givenMockedContructorWithArgument_whenCoffeeMade_thenMockDependencyReturned() {
try (MockedConstruction<WaterTank> mockTank = mockConstruction(WaterTank.class, (mock, context) -> {
int mils = (int) context.arguments().get(0);
when(mock.getMils()).thenReturn(mils);
});
MockedConstruction<Grinder> mockGrinder = mockConstruction(Grinder.class)) {
CoffeeMachine machine = new CoffeeMachine(100);
Grinder grinder = mockGrinder.constructed()
.get(0);
when(grinder.getBeans()).thenReturn("Kenyan");
assertEquals("Finished making a delicious Americano made with Kenyan beans", machine.makeCoffee());
}
}
}

View File

@ -0,0 +1,50 @@
package com.baeldung.construction;
import org.junit.jupiter.api.Test;
import org.mockito.Answers;
import org.mockito.MockedConstruction;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.withSettings;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.List;
import static org.mockito.Mockito.mockConstruction;
class FruitUnitTest {
@Test
void givenMockedContructor_whenFruitCreated_thenMockIsReturned() {
assertEquals("Apple", new Fruit().getName());
assertEquals("Red", new Fruit().getColour());
try (MockedConstruction<Fruit> mock = mockConstruction(Fruit.class)) {
Fruit fruit = new Fruit();
when(fruit.getName()).thenReturn("Banana");
when(fruit.getColour()).thenReturn("Yellow");
assertEquals("Banana", fruit.getName());
assertEquals("Yellow", fruit.getColour());
List<Fruit> constructed = mock.constructed();
assertEquals(1, constructed.size());
}
}
@Test
void givenMockedContructorWithNewDefaultAnswer_whenFruitCreated_thenRealMethodInvoked() {
try (MockedConstruction<Fruit> mock = mockConstruction(Fruit.class, withSettings().defaultAnswer(Answers.CALLS_REAL_METHODS))) {
Fruit fruit = new Fruit();
assertEquals("Apple", fruit.getName());
assertEquals("Red", fruit.getColour());
List<Fruit> constructed = mock.constructed();
assertEquals(1, constructed.size());
}
}
}