diff --git a/persistence-modules/spring-data-mongodb-reactive/README.md b/persistence-modules/spring-data-mongodb-reactive/README.md
new file mode 100644
index 0000000000..0d80fc8b92
--- /dev/null
+++ b/persistence-modules/spring-data-mongodb-reactive/README.md
@@ -0,0 +1,10 @@
+## Spring Data Reactive Project
+
+This module contains articles about reactive Spring 5 Data
+
+### The Course
+The "REST With Spring" Classes: http://bit.ly/restwithspring
+
+### Relevant Articles
+- [Spring Data Reactive Repositories with MongoDB](https://www.baeldung.com/spring-data-mongodb-reactive)
+- [Spring Data MongoDB Tailable Cursors](https://www.baeldung.com/spring-data-mongodb-tailable-cursors)
\ No newline at end of file
diff --git a/persistence-modules/spring-data-mongodb-reactive/pom.xml b/persistence-modules/spring-data-mongodb-reactive/pom.xml
new file mode 100644
index 0000000000..85c9a4c4b6
--- /dev/null
+++ b/persistence-modules/spring-data-mongodb-reactive/pom.xml
@@ -0,0 +1,131 @@
+
+
+ 4.0.0
+ spring-data-mongodb-reactive
+ spring-data-mongodb-reactive
+ jar
+
+
+ com.baeldung
+ parent-boot-2
+ 0.0.1-SNAPSHOT
+ ../../parent-boot-2
+
+
+
+
+ io.projectreactor
+ reactor-core
+ ${reactor-core.version}
+
+
+ org.springframework.boot
+ spring-boot-starter-data-mongodb-reactive
+
+
+ org.springframework.boot
+ spring-boot-starter-data-mongodb
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.projectlombok
+ lombok
+
+
+ io.projectreactor
+ reactor-test
+ test
+
+
+ io.reactivex.rxjava2
+ rxjava
+
+
+ org.springframework
+ spring-test
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ de.flapdoodle.embed
+ de.flapdoodle.embed.mongo
+ test
+
+
+ org.springframework.boot
+ spring-boot-starter-webflux
+
+
+ org.springframework
+ spring-tx
+ ${spring-tx.version}
+
+
+ com.h2database
+ h2
+
+
+ org.apache.httpcomponents
+ httpclient
+ ${httpclient.version}
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ ${java.version}
+ ${java.version}
+
+
+
+
+ default-compile
+ none
+
+
+
+ default-testCompile
+ none
+
+
+ java-compile
+ compile
+
+ compile
+
+
+
+ java-test-compile
+ test-compile
+
+ testCompile
+
+
+
+
+
+
+
+
+ 5.3.15
+ 4.5.2
+ 3.3.1.RELEASE
+
+
+
\ No newline at end of file
diff --git a/persistence-modules/spring-data-mongodb-reactive/src/test/java/com/baeldung/SpringContextTest.java b/persistence-modules/spring-data-mongodb-reactive/src/test/java/com/baeldung/SpringContextTest.java
new file mode 100644
index 0000000000..bedb30fcaa
--- /dev/null
+++ b/persistence-modules/spring-data-mongodb-reactive/src/test/java/com/baeldung/SpringContextTest.java
@@ -0,0 +1,17 @@
+package com.baeldung;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import com.baeldung.reactive.Spring5ReactiveApplication;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes = Spring5ReactiveApplication.class)
+public class SpringContextTest {
+
+ @Test
+ public void whenSpringContextIsBootstrapped_thenNoExceptions() {
+ }
+}
diff --git a/persistence-modules/spring-data-mongodb-reactive/src/test/resources/application.properties b/persistence-modules/spring-data-mongodb-reactive/src/test/resources/application.properties
new file mode 100644
index 0000000000..a5b5fb9804
--- /dev/null
+++ b/persistence-modules/spring-data-mongodb-reactive/src/test/resources/application.properties
@@ -0,0 +1 @@
+spring.mongodb.embedded.version=4.4.9
\ No newline at end of file
diff --git a/testing-modules/.project b/testing-modules/.project
new file mode 100644
index 0000000000..b177d32810
--- /dev/null
+++ b/testing-modules/.project
@@ -0,0 +1,17 @@
+
+
+ testing-modules
+
+
+
+
+
+ org.eclipse.m2e.core.maven2Builder
+
+
+
+
+
+ org.eclipse.m2e.core.maven2Nature
+
+
diff --git a/testing-modules/.settings/org.eclipse.core.resources.prefs b/testing-modules/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000000..99f26c0203
--- /dev/null
+++ b/testing-modules/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+encoding/=UTF-8
diff --git a/testing-modules/assertion-libraries/.classpath b/testing-modules/assertion-libraries/.classpath
new file mode 100644
index 0000000000..8c45832050
--- /dev/null
+++ b/testing-modules/assertion-libraries/.classpath
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/testing-modules/assertion-libraries/.project b/testing-modules/assertion-libraries/.project
new file mode 100644
index 0000000000..adabe74477
--- /dev/null
+++ b/testing-modules/assertion-libraries/.project
@@ -0,0 +1,23 @@
+
+
+ assertion-libraries
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.m2e.core.maven2Builder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+ org.eclipse.m2e.core.maven2Nature
+
+
diff --git a/testing-modules/assertion-libraries/.settings/org.eclipse.core.resources.prefs b/testing-modules/assertion-libraries/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000000..f9fe34593f
--- /dev/null
+++ b/testing-modules/assertion-libraries/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,4 @@
+eclipse.preferences.version=1
+encoding//src/main/java=UTF-8
+encoding//src/test/java=UTF-8
+encoding/=UTF-8
diff --git a/testing-modules/assertion-libraries/.settings/org.eclipse.jdt.apt.core.prefs b/testing-modules/assertion-libraries/.settings/org.eclipse.jdt.apt.core.prefs
new file mode 100644
index 0000000000..d4313d4b25
--- /dev/null
+++ b/testing-modules/assertion-libraries/.settings/org.eclipse.jdt.apt.core.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.apt.aptEnabled=false
diff --git a/testing-modules/assertion-libraries/.settings/org.eclipse.jdt.core.prefs b/testing-modules/assertion-libraries/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000000..99a63d5466
--- /dev/null
+++ b/testing-modules/assertion-libraries/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,9 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=11
+org.eclipse.jdt.core.compiler.compliance=11
+org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore
+org.eclipse.jdt.core.compiler.processAnnotations=disabled
+org.eclipse.jdt.core.compiler.release=enabled
+org.eclipse.jdt.core.compiler.source=11
diff --git a/testing-modules/junit-5-basics/.classpath b/testing-modules/junit-5-basics/.classpath
new file mode 100644
index 0000000000..68a8fcf14b
--- /dev/null
+++ b/testing-modules/junit-5-basics/.classpath
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/testing-modules/junit-5-basics/.project b/testing-modules/junit-5-basics/.project
new file mode 100644
index 0000000000..12782c64ef
--- /dev/null
+++ b/testing-modules/junit-5-basics/.project
@@ -0,0 +1,23 @@
+
+
+ junit-5-basics
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.m2e.core.maven2Builder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+ org.eclipse.m2e.core.maven2Nature
+
+
diff --git a/testing-modules/junit-5-basics/.settings/org.eclipse.core.resources.prefs b/testing-modules/junit-5-basics/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000000..29abf99956
--- /dev/null
+++ b/testing-modules/junit-5-basics/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,6 @@
+eclipse.preferences.version=1
+encoding//src/main/java=UTF-8
+encoding//src/main/resources=UTF-8
+encoding//src/test/java=UTF-8
+encoding//src/test/resources=UTF-8
+encoding/=UTF-8
diff --git a/testing-modules/junit-5-basics/.settings/org.eclipse.jdt.apt.core.prefs b/testing-modules/junit-5-basics/.settings/org.eclipse.jdt.apt.core.prefs
new file mode 100644
index 0000000000..d4313d4b25
--- /dev/null
+++ b/testing-modules/junit-5-basics/.settings/org.eclipse.jdt.apt.core.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.apt.aptEnabled=false
diff --git a/testing-modules/junit-5-basics/.settings/org.eclipse.jdt.core.prefs b/testing-modules/junit-5-basics/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000000..99a63d5466
--- /dev/null
+++ b/testing-modules/junit-5-basics/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,9 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=11
+org.eclipse.jdt.core.compiler.compliance=11
+org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore
+org.eclipse.jdt.core.compiler.processAnnotations=disabled
+org.eclipse.jdt.core.compiler.release=enabled
+org.eclipse.jdt.core.compiler.source=11
diff --git a/testing-modules/mockito-2/src/main/java/com/baeldung/constructor/PaymentProcessor.java b/testing-modules/mockito-2/src/main/java/com/baeldung/constructor/PaymentProcessor.java
new file mode 100644
index 0000000000..39b2b74bd0
--- /dev/null
+++ b/testing-modules/mockito-2/src/main/java/com/baeldung/constructor/PaymentProcessor.java
@@ -0,0 +1,22 @@
+package com.baeldung.constructor;
+
+public class PaymentProcessor {
+
+ private final PaymentService paymentService;
+
+ public PaymentProcessor(PaymentService paymentService) {
+ this.paymentService = paymentService;
+ }
+
+ public PaymentProcessor() {
+ this.paymentService = new PaymentService();
+ }
+
+ public PaymentProcessor(String paymentMode) {
+ this.paymentService = new PaymentService(paymentMode);
+ }
+
+ public String processPayment(){
+ return paymentService.processPayment();
+ }
+}
diff --git a/testing-modules/mockito-2/src/main/java/com/baeldung/constructor/PaymentService.java b/testing-modules/mockito-2/src/main/java/com/baeldung/constructor/PaymentService.java
new file mode 100644
index 0000000000..5194ed7e21
--- /dev/null
+++ b/testing-modules/mockito-2/src/main/java/com/baeldung/constructor/PaymentService.java
@@ -0,0 +1,19 @@
+package com.baeldung.constructor;
+
+public class PaymentService {
+
+ private final String paymentMode;
+
+ public PaymentService(String paymentMode) {
+ this.paymentMode = paymentMode;
+ }
+
+ public PaymentService() {
+ this.paymentMode = "Cash";
+ }
+
+ public String processPayment(){
+ // simulate processing payment and returns the payment mode
+ return this.paymentMode;
+ }
+}
diff --git a/testing-modules/mockito-2/src/main/java/com/baeldung/nullmatcher/Helper.java b/testing-modules/mockito-2/src/main/java/com/baeldung/nullmatcher/Helper.java
new file mode 100644
index 0000000000..c7e7ecdd28
--- /dev/null
+++ b/testing-modules/mockito-2/src/main/java/com/baeldung/nullmatcher/Helper.java
@@ -0,0 +1,9 @@
+package com.baeldung.nullmatcher;
+
+class Helper {
+
+ String concat(String a, String b) {
+ return a + b;
+ }
+
+}
diff --git a/testing-modules/mockito-2/src/main/java/com/baeldung/nullmatcher/Main.java b/testing-modules/mockito-2/src/main/java/com/baeldung/nullmatcher/Main.java
new file mode 100644
index 0000000000..75a3113736
--- /dev/null
+++ b/testing-modules/mockito-2/src/main/java/com/baeldung/nullmatcher/Main.java
@@ -0,0 +1,11 @@
+package com.baeldung.nullmatcher;
+
+class Main {
+
+ Helper helper = new Helper();
+
+ String methodUnderTest() {
+ return helper.concat("Baeldung", null);
+ }
+
+}
diff --git a/testing-modules/mockito-2/src/main/java/com/baeldung/onemethodmultipleparams/ExampleService.java b/testing-modules/mockito-2/src/main/java/com/baeldung/onemethodmultipleparams/ExampleService.java
new file mode 100644
index 0000000000..7177013721
--- /dev/null
+++ b/testing-modules/mockito-2/src/main/java/com/baeldung/onemethodmultipleparams/ExampleService.java
@@ -0,0 +1,7 @@
+package com.baeldung.onemethodmultipleparams;
+
+public class ExampleService {
+ public int getValue(int arg) {
+ return 1;
+ }
+}
diff --git a/testing-modules/mockito-2/src/main/java/com/baeldung/singleton/CacheManager.java b/testing-modules/mockito-2/src/main/java/com/baeldung/singleton/CacheManager.java
new file mode 100644
index 0000000000..51aea926b4
--- /dev/null
+++ b/testing-modules/mockito-2/src/main/java/com/baeldung/singleton/CacheManager.java
@@ -0,0 +1,29 @@
+package com.baeldung.singleton;
+
+import java.util.HashMap;
+
+public class CacheManager {
+ private final HashMap map;
+
+ private static CacheManager instance;
+
+ private CacheManager() {
+ map = new HashMap<>();
+ }
+
+ public static CacheManager getInstance() {
+ if(instance == null) {
+ instance = new CacheManager();
+ }
+
+ return instance;
+ }
+
+ public T getValue(String key, Class clazz) {
+ return clazz.cast(map.get(key));
+ }
+
+ public Object setValue(String key, Object value) {
+ return map.put(key, value);
+ }
+}
\ No newline at end of file
diff --git a/testing-modules/mockito-2/src/main/java/com/baeldung/singleton/Product.java b/testing-modules/mockito-2/src/main/java/com/baeldung/singleton/Product.java
new file mode 100644
index 0000000000..58905e3488
--- /dev/null
+++ b/testing-modules/mockito-2/src/main/java/com/baeldung/singleton/Product.java
@@ -0,0 +1,27 @@
+package com.baeldung.singleton;
+
+public class Product {
+ private String name;
+ private String description;
+
+ public Product(String name, String description) {
+ this.name = name;
+ this.description = description;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+}
diff --git a/testing-modules/mockito-2/src/main/java/com/baeldung/singleton/ProductDAO.java b/testing-modules/mockito-2/src/main/java/com/baeldung/singleton/ProductDAO.java
new file mode 100644
index 0000000000..ae9562561b
--- /dev/null
+++ b/testing-modules/mockito-2/src/main/java/com/baeldung/singleton/ProductDAO.java
@@ -0,0 +1,8 @@
+package com.baeldung.singleton;
+
+public class ProductDAO {
+ public Product getProduct(String productName) {
+
+ return new Product(productName, "description");
+ }
+}
diff --git a/testing-modules/mockito-2/src/main/java/com/baeldung/singleton/ProductService.java b/testing-modules/mockito-2/src/main/java/com/baeldung/singleton/ProductService.java
new file mode 100644
index 0000000000..382087d96d
--- /dev/null
+++ b/testing-modules/mockito-2/src/main/java/com/baeldung/singleton/ProductService.java
@@ -0,0 +1,26 @@
+package com.baeldung.singleton;
+
+public class ProductService {
+
+ private final ProductDAO productDAO;
+ private final CacheManager cacheManager;
+
+ public ProductService(ProductDAO productDAO) {
+ this.productDAO = productDAO;
+ this.cacheManager = CacheManager.getInstance();
+ }
+
+ public ProductService(ProductDAO productDAO, CacheManager cacheManager) {
+ this.productDAO = productDAO;
+ this.cacheManager = cacheManager;
+ }
+
+ public Product getProduct(String productName) {
+ Product product = cacheManager.getValue(productName, Product.class);
+ if (product == null) {
+ product = productDAO.getProduct(productName);
+ }
+
+ return product;
+ }
+}
diff --git a/testing-modules/mockito-2/src/main/java/com/baeldung/wantedbutnotinvocked/Helper.java b/testing-modules/mockito-2/src/main/java/com/baeldung/wantedbutnotinvocked/Helper.java
new file mode 100644
index 0000000000..6a7cd15703
--- /dev/null
+++ b/testing-modules/mockito-2/src/main/java/com/baeldung/wantedbutnotinvocked/Helper.java
@@ -0,0 +1,9 @@
+package com.baeldung.wantedbutnotinvocked;
+
+class Helper {
+
+ String getBaeldungString() {
+ return "Baeldung";
+ }
+
+}
diff --git a/testing-modules/mockito-2/src/main/java/com/baeldung/wantedbutnotinvocked/Main.java b/testing-modules/mockito-2/src/main/java/com/baeldung/wantedbutnotinvocked/Main.java
new file mode 100644
index 0000000000..bee3662214
--- /dev/null
+++ b/testing-modules/mockito-2/src/main/java/com/baeldung/wantedbutnotinvocked/Main.java
@@ -0,0 +1,14 @@
+package com.baeldung.wantedbutnotinvocked;
+
+class Main {
+
+ Helper helper = new Helper();
+
+ String methodUnderTest(int i) {
+ if (i > 5) {
+ return helper.getBaeldungString();
+ }
+ return "Hello";
+ }
+
+}
diff --git a/testing-modules/mockito-2/src/test/java/com/baeldung/constructor/PaymentServiceUnitTest.java b/testing-modules/mockito-2/src/test/java/com/baeldung/constructor/PaymentServiceUnitTest.java
new file mode 100644
index 0000000000..16be4a728b
--- /dev/null
+++ b/testing-modules/mockito-2/src/test/java/com/baeldung/constructor/PaymentServiceUnitTest.java
@@ -0,0 +1,63 @@
+package com.baeldung.constructor;
+
+import static org.mockito.Mockito.when;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.mockito.MockedConstruction;
+import org.mockito.Mockito;
+
+class PaymentServiceUnitTest {
+
+ @Test
+ void whenConstructorInvokedWithInitializer_ThenMockObjectShouldBeCreated(){
+ try(MockedConstruction mockPaymentService = Mockito.mockConstruction(PaymentService.class,(mock,context)-> when(mock.processPayment()).thenReturn("Credit"))){
+ PaymentProcessor paymentProcessor = new PaymentProcessor();
+ Assertions.assertEquals(1,mockPaymentService.constructed().size());
+ Assertions.assertEquals("Credit", paymentProcessor.processPayment());
+ }
+ }
+
+ @Test
+ void whenConstructorInvokedWithoutInitializer_ThenMockObjectShouldBeCreatedWithNullFields(){
+ try(MockedConstruction mockPaymentService = Mockito.mockConstruction(PaymentService.class)){
+ PaymentProcessor paymentProcessor = new PaymentProcessor();
+ Assertions.assertEquals(1,mockPaymentService.constructed().size());
+ Assertions.assertNull(paymentProcessor.processPayment());
+ }
+ }
+
+ @Test
+ void whenConstructorInvokedWithParameters_ThenMockObjectShouldBeCreated(){
+ try(MockedConstruction mockPaymentService = Mockito.mockConstruction(PaymentService.class,(mock, context) -> when(mock.processPayment()).thenReturn("Credit"))){
+ PaymentProcessor paymentProcessor = new PaymentProcessor("Debit");
+ Assertions.assertEquals(1,mockPaymentService.constructed().size());
+ Assertions.assertEquals("Credit", paymentProcessor.processPayment());
+ }
+ }
+
+ @Test
+ void whenMultipleConstructorsInvoked_ThenMultipleMockObjectsShouldBeCreated(){
+ try(MockedConstruction mockPaymentService = Mockito.mockConstruction(PaymentService.class)){
+ PaymentProcessor paymentProcessor = new PaymentProcessor();
+ PaymentProcessor secondPaymentProcessor = new PaymentProcessor();
+ PaymentProcessor thirdPaymentProcessor = new PaymentProcessor("Debit");
+
+ when(mockPaymentService.constructed().get(0).processPayment()).thenReturn("Credit");
+ when(mockPaymentService.constructed().get(1).processPayment()).thenReturn("Online Banking");
+
+ Assertions.assertEquals(3,mockPaymentService.constructed().size());
+ Assertions.assertEquals("Credit", paymentProcessor.processPayment());
+ Assertions.assertEquals("Online Banking", secondPaymentProcessor.processPayment());
+ Assertions.assertNull(thirdPaymentProcessor.processPayment());
+ }
+ }
+
+ @Test
+ void whenDependencyInjectionIsUsed_ThenMockObjectShouldBeCreated(){
+ PaymentService mockPaymentService = Mockito.mock(PaymentService.class);
+ PaymentProcessor paymentProcessor = new PaymentProcessor(mockPaymentService);
+ when(mockPaymentService.processPayment()).thenReturn("Online Banking");
+ Assertions.assertEquals("Online Banking", paymentProcessor.processPayment());
+ }
+}
diff --git a/testing-modules/mockito-2/src/test/java/com/baeldung/nullmatcher/MainUnitTest.java b/testing-modules/mockito-2/src/test/java/com/baeldung/nullmatcher/MainUnitTest.java
new file mode 100644
index 0000000000..7da415e4d3
--- /dev/null
+++ b/testing-modules/mockito-2/src/test/java/com/baeldung/nullmatcher/MainUnitTest.java
@@ -0,0 +1,40 @@
+package com.baeldung.nullmatcher;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.isNull;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+
+class MainUnitTest {
+
+ @Mock
+ Helper helper;
+
+ @InjectMocks
+ Main main;
+
+ @BeforeEach
+ void openMocks() {
+ MockitoAnnotations.openMocks(this);
+ }
+
+ @Test
+ void whenMethodUnderTest_thenSecondParameterNull() {
+ main.methodUnderTest();
+ Mockito.verify(helper)
+ .concat("Baeldung", null);
+ }
+
+ @Test
+ void whenMethodUnderTest_thenSecondParameterNullWithMatchers() {
+ main.methodUnderTest();
+ Mockito.verify(helper)
+ .concat(any(), isNull());
+ }
+
+}
diff --git a/testing-modules/mockito-2/src/test/java/com/baeldung/onemethodmultipleparams/OneMethodMultipleParamsUnitTest.java b/testing-modules/mockito-2/src/test/java/com/baeldung/onemethodmultipleparams/OneMethodMultipleParamsUnitTest.java
new file mode 100644
index 0000000000..0633a5a2f0
--- /dev/null
+++ b/testing-modules/mockito-2/src/test/java/com/baeldung/onemethodmultipleparams/OneMethodMultipleParamsUnitTest.java
@@ -0,0 +1,63 @@
+package com.baeldung.onemethodmultipleparams;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.when;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnitRunner;
+
+@RunWith(MockitoJUnitRunner.class)
+public class OneMethodMultipleParamsUnitTest {
+
+ @Mock
+ ExampleService exampleService;
+
+ @Test
+ public void givenAMethod_whenStubbingForMultipleArguments_thenExpectDifferentResults() {
+ when(exampleService.getValue(10)).thenReturn(100);
+ when(exampleService.getValue(20)).thenReturn(200);
+ when(exampleService.getValue(30)).thenReturn(300);
+
+ assertEquals(100, exampleService.getValue(10));
+ assertEquals(200, exampleService.getValue(20));
+ assertEquals(300, exampleService.getValue(30));
+ }
+
+ @Test
+ public void givenAMethod_whenUsingThenAnswer_thenExpectDifferentReults() {
+ when(exampleService.getValue(anyInt())).thenAnswer(invocation -> {
+ int argument = (int) invocation.getArguments()[0];
+ int result;
+ switch (argument) {
+ case 25:
+ result = 125;
+ break;
+ case 50:
+ result = 150;
+ break;
+ case 75:
+ result = 175;
+ break;
+ default:
+ result = 0;
+ }
+ return result;
+ });
+ assertEquals(125, exampleService.getValue(25));
+ assertEquals(150, exampleService.getValue(50));
+ assertEquals(175, exampleService.getValue(75));
+ }
+
+ @Test
+ public void givenAMethod_whenUsingConsecutiveStubbing_thenExpectResultsInOrder() {
+ when(exampleService.getValue(anyInt())).thenReturn(9, 18, 27);
+ assertEquals(9, exampleService.getValue(1));
+ assertEquals(18, exampleService.getValue(1));
+ assertEquals(27, exampleService.getValue(1));
+ assertEquals(27, exampleService.getValue(1));
+ }
+
+}
diff --git a/testing-modules/mockito-2/src/test/java/com/baeldung/singleton/ProductServiceTest.java b/testing-modules/mockito-2/src/test/java/com/baeldung/singleton/ProductServiceTest.java
new file mode 100644
index 0000000000..792d472f94
--- /dev/null
+++ b/testing-modules/mockito-2/src/test/java/com/baeldung/singleton/ProductServiceTest.java
@@ -0,0 +1,40 @@
+package com.baeldung.singleton;
+
+import org.junit.jupiter.api.Test;
+import org.mockito.MockedStatic;
+import org.mockito.Mockito;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.*;
+
+class ProductServiceUnitTest {
+
+ @Test
+ void givenValueExistsInCache_whenGetProduct_thenDAOIsNotCalled() {
+ ProductDAO productDAO = mock(ProductDAO.class);
+ CacheManager cacheManager = mock(CacheManager.class);
+ Product product = new Product("product1", "description");
+ ProductService productService = new ProductService(productDAO, cacheManager);
+
+ when(cacheManager.getValue(any(), any())).thenReturn(product);
+
+ productService.getProduct("product1");
+
+ Mockito.verify(productDAO, times(0)).getProduct(any());
+ }
+
+ @Test
+ void givenValueExistsInCache_whenGetProduct_thenDAOIsNotCalled_mockingStatic() {
+ ProductDAO productDAO = mock(ProductDAO.class);
+ CacheManager cacheManager = mock(CacheManager.class);
+ Product product = new Product("product1", "description");
+
+ try (MockedStatic cacheManagerMock = mockStatic(CacheManager.class)) {
+ cacheManagerMock.when(CacheManager::getInstance).thenReturn(cacheManager);
+ when(cacheManager.getValue(any(), any())).thenReturn(product);
+ ProductService productService = new ProductService(productDAO);
+ productService.getProduct("product1");
+ Mockito.verify(productDAO, times(0)).getProduct(any());
+ }
+ }
+}
\ No newline at end of file
diff --git a/testing-modules/mockito-2/src/test/java/com/baeldung/wantedbutnotinvocked/MainUnitTest.java b/testing-modules/mockito-2/src/test/java/com/baeldung/wantedbutnotinvocked/MainUnitTest.java
new file mode 100644
index 0000000000..b4d9f2c386
--- /dev/null
+++ b/testing-modules/mockito-2/src/test/java/com/baeldung/wantedbutnotinvocked/MainUnitTest.java
@@ -0,0 +1,38 @@
+package com.baeldung.wantedbutnotinvocked;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+
+class MainUnitTest {
+
+ @Mock
+ Helper helper;
+
+ @InjectMocks
+ Main main = new Main();
+
+ @BeforeEach
+ void setUp() {
+ MockitoAnnotations.openMocks(this);
+ }
+
+ @Test
+ void givenValueUpperThan5_WhenMethodUnderTest_ThenDelegatesToHelperClass() {
+ main.methodUnderTest(7);
+ Mockito.verify(helper)
+ .getBaeldungString();
+ }
+
+ // Uncomment the next line to see the error
+ // @Test
+ void givenValueLowerThan5_WhenMethodUnderTest_ThenDelegatesToGetBaeldungString() {
+ main.methodUnderTest(3);
+ Mockito.verify(helper)
+ .getBaeldungString();
+ }
+
+}
diff --git a/testing-modules/spring-mockito/README.md b/testing-modules/spring-mockito/README.md
new file mode 100644
index 0000000000..73b102623f
--- /dev/null
+++ b/testing-modules/spring-mockito/README.md
@@ -0,0 +1,7 @@
+## Spring Mockito
+
+This module contains articles about Spring with Mockito
+
+### Relevant Articles:
+- [Injecting Mockito Mocks into Spring Beans](https://www.baeldung.com/injecting-mocks-in-spring)
+- [SpringRunner vs MockitoJUnitRunner](https://www.baeldung.com/junit-springrunner-vs-mockitojunitrunner)
diff --git a/testing-modules/spring-mockito/pom.xml b/testing-modules/spring-mockito/pom.xml
new file mode 100644
index 0000000000..6283ea2d1f
--- /dev/null
+++ b/testing-modules/spring-mockito/pom.xml
@@ -0,0 +1,35 @@
+
+
+ 4.0.0
+ spring-mockito
+ 0.0.1-SNAPSHOT
+ spring-mockito
+ jar
+ Injecting Mockito Mocks into Spring Beans
+
+
+ com.baeldung
+ parent-boot-2
+ 0.0.1-SNAPSHOT
+ ../../parent-boot-2
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.mockito
+ mockito-core
+ ${mockito.version}
+
+
+ org.projectlombok
+ lombok
+
+
+
+
\ No newline at end of file
diff --git a/testing-modules/spring-mockito/src/main/java/com/baeldung/runners/DataProvider.java b/testing-modules/spring-mockito/src/main/java/com/baeldung/runners/DataProvider.java
new file mode 100644
index 0000000000..303cd6f7cf
--- /dev/null
+++ b/testing-modules/spring-mockito/src/main/java/com/baeldung/runners/DataProvider.java
@@ -0,0 +1,17 @@
+package com.baeldung.runners;
+
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+@Component
+public class DataProvider {
+
+ private final List memory = Stream.of("baeldung", "java", "dummy").collect(Collectors.toList());
+
+ public Stream getValues() {
+ return memory.stream();
+ }
+}
diff --git a/testing-modules/spring-mockito/src/main/java/com/baeldung/runners/StringConverter.java b/testing-modules/spring-mockito/src/main/java/com/baeldung/runners/StringConverter.java
new file mode 100644
index 0000000000..0ed34cab08
--- /dev/null
+++ b/testing-modules/spring-mockito/src/main/java/com/baeldung/runners/StringConverter.java
@@ -0,0 +1,22 @@
+package com.baeldung.runners;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+@Service
+public class StringConverter {
+
+ private final DataProvider dataProvider;
+
+ @Autowired
+ public StringConverter(DataProvider dataProvider) {
+ this.dataProvider = dataProvider;
+ }
+
+ public List convert() {
+ return dataProvider.getValues().map(String::toUpperCase).collect(Collectors.toList());
+ }
+}
diff --git a/testing-modules/spring-mockito/src/main/java/com/baeldung/runners/StringConverterStarter.java b/testing-modules/spring-mockito/src/main/java/com/baeldung/runners/StringConverterStarter.java
new file mode 100644
index 0000000000..6244d9bfa7
--- /dev/null
+++ b/testing-modules/spring-mockito/src/main/java/com/baeldung/runners/StringConverterStarter.java
@@ -0,0 +1,11 @@
+package com.baeldung.runners;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class StringConverterStarter {
+ public static void main(String[] args) {
+ SpringApplication.run(StringConverterStarter.class, args);
+ }
+}
diff --git a/testing-modules/spring-mockito/src/main/resources/application.properties b/testing-modules/spring-mockito/src/main/resources/application.properties
new file mode 100644
index 0000000000..0cae63ed98
--- /dev/null
+++ b/testing-modules/spring-mockito/src/main/resources/application.properties
@@ -0,0 +1,2 @@
+spring.main.allow-bean-definition-overriding=true
+spring.main.web-application-type=none
\ No newline at end of file
diff --git a/testing-modules/spring-mockito/src/main/resources/logback.xml b/testing-modules/spring-mockito/src/main/resources/logback.xml
new file mode 100644
index 0000000000..7d900d8ea8
--- /dev/null
+++ b/testing-modules/spring-mockito/src/main/resources/logback.xml
@@ -0,0 +1,13 @@
+
+
+
+
+ %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/testing-modules/spring-mockito/src/test/java/com/baeldung/UserServiceUnitTest.java b/testing-modules/spring-mockito/src/test/java/com/baeldung/UserServiceUnitTest.java
new file mode 100644
index 0000000000..11c7b4d8a8
--- /dev/null
+++ b/testing-modules/spring-mockito/src/test/java/com/baeldung/UserServiceUnitTest.java
@@ -0,0 +1,31 @@
+package com.baeldung;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+@ActiveProfiles("test")
+@RunWith(SpringJUnit4ClassRunner.class)
+@SpringBootTest(classes = MocksApplication.class)
+public class UserServiceUnitTest {
+
+ @Autowired
+ private UserService userService;
+
+ @Autowired
+ private NameService nameService;
+
+ @Test
+ public void whenUserIdIsProvided_thenRetrievedNameIsCorrect() {
+ Mockito.when(nameService.getUserName("SomeId")).thenReturn("Mock user name");
+
+ String testName = userService.getUserName("SomeId");
+
+ Assert.assertEquals("Mock user name", testName);
+ }
+}
\ No newline at end of file
diff --git a/testing-modules/spring-mockito/src/test/java/com/baeldung/runners/StringConverterMockitoRunnerUnitTest.java b/testing-modules/spring-mockito/src/test/java/com/baeldung/runners/StringConverterMockitoRunnerUnitTest.java
new file mode 100644
index 0000000000..80b8a8bdbb
--- /dev/null
+++ b/testing-modules/spring-mockito/src/test/java/com/baeldung/runners/StringConverterMockitoRunnerUnitTest.java
@@ -0,0 +1,30 @@
+package com.baeldung.runners;
+
+import lombok.val;
+import org.assertj.core.api.Assertions;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.junit.MockitoJUnitRunner;
+
+import java.util.stream.Stream;
+
+@RunWith(MockitoJUnitRunner.class)
+public class StringConverterMockitoRunnerUnitTest {
+ @Mock
+ private DataProvider dataProvider;
+
+ @InjectMocks
+ private StringConverter stringConverter;
+
+ @Test
+ public void givenStrings_whenConvert_thenReturnUpperCase() {
+ Mockito.when(dataProvider.getValues()).thenReturn(Stream.of("first", "second"));
+
+ val result = stringConverter.convert();
+
+ Assertions.assertThat(result).contains("FIRST", "SECOND");
+ }
+}
\ No newline at end of file
diff --git a/testing-modules/spring-mockito/src/test/java/com/baeldung/runners/StringConverterSpringRunnerUnitTest.java b/testing-modules/spring-mockito/src/test/java/com/baeldung/runners/StringConverterSpringRunnerUnitTest.java
new file mode 100644
index 0000000000..4408cd71ca
--- /dev/null
+++ b/testing-modules/spring-mockito/src/test/java/com/baeldung/runners/StringConverterSpringRunnerUnitTest.java
@@ -0,0 +1,32 @@
+package com.baeldung.runners;
+
+import lombok.val;
+import org.assertj.core.api.Assertions;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import java.util.stream.Stream;
+
+@ContextConfiguration(classes = StringConverter.class)
+@RunWith(SpringRunner.class)
+public class StringConverterSpringRunnerUnitTest {
+ @MockBean
+ private DataProvider dataProvider;
+
+ @Autowired
+ private StringConverter stringConverter;
+
+ @Test
+ public void givenStrings_whenConvert_thenReturnUpperCase() {
+ Mockito.when(dataProvider.getValues()).thenReturn(Stream.of("first", "second"));
+
+ val result = stringConverter.convert();
+
+ Assertions.assertThat(result).contains("FIRST", "SECOND");
+ }
+}
\ No newline at end of file
diff --git a/testing-modules/spring-mockito/src/test/java/com/baeldung/runners/StringConverterWithInitUnitTest.java b/testing-modules/spring-mockito/src/test/java/com/baeldung/runners/StringConverterWithInitUnitTest.java
new file mode 100644
index 0000000000..a41fa20ca0
--- /dev/null
+++ b/testing-modules/spring-mockito/src/test/java/com/baeldung/runners/StringConverterWithInitUnitTest.java
@@ -0,0 +1,37 @@
+package com.baeldung.runners;
+
+import lombok.val;
+import org.assertj.core.api.Assertions;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+
+import java.util.stream.Stream;
+
+public class StringConverterWithInitUnitTest {
+ @Mock
+ private DataProvider dataProvider;
+
+ @InjectMocks
+ private StringConverter stringConverter;
+
+ @Before
+ public void init() {
+ MockitoAnnotations.openMocks(this);
+ // or
+ // dataProvider = Mockito.mock(DataProvider.class);
+ // stringConverter = new StringConverter(dataProvider);
+ }
+
+ @Test
+ public void givenStrings_whenConvert_thenReturnUpperCase() {
+ Mockito.when(dataProvider.getValues()).thenReturn(Stream.of("first", "second"));
+
+ val result = stringConverter.convert();
+
+ Assertions.assertThat(result).contains("FIRST", "SECOND");
+ }
+}
\ No newline at end of file