diff --git a/mockito2/.gitignore b/mockito2/.gitignore
new file mode 100644
index 0000000000..7f300600e6
--- /dev/null
+++ b/mockito2/.gitignore
@@ -0,0 +1,14 @@
+*.class
+
+.settings
+.project
+
+#folders#
+/target
+/src/main/webapp/WEB-INF/classes
+*/META-INF/*
+
+# Packaged files #
+*.jar
+*.war
+*.ear
diff --git a/mockito2/README.md b/mockito2/README.md
new file mode 100644
index 0000000000..587f1341bb
--- /dev/null
+++ b/mockito2/README.md
@@ -0,0 +1,5 @@
+=========
+
+## Mockito 2 and Java 8 Tips
+
+Examples on how to leverage Java 8 new features with Mockito version 2
diff --git a/mockito2/pom.xml b/mockito2/pom.xml
new file mode 100644
index 0000000000..e116647009
--- /dev/null
+++ b/mockito2/pom.xml
@@ -0,0 +1,98 @@
+
+
+ 4.0.0
+ com.baeldung
+ mockito2
+ 0.0.1-SNAPSHOT
+ jar
+ mockito-2-with-java8
+
+
+
+
+ junit
+ junit
+ ${junit.version}
+ test
+
+
+
+ org.mockito
+ mockito-core
+ ${mockito.version}
+ test
+
+
+
+
+
+
+ maven-compiler-plugin
+ ${maven-compiler-plugin.version}
+
+ 1.8
+ 1.8
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ ${maven-surefire-plugin.version}
+
+
+ **/*IntegrationTest.java
+ **/*LiveTest.java
+
+
+
+
+
+
+
+
+ integration
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+
+ integration-test
+
+ test
+
+
+
+ **/*LiveTest.java
+
+
+ **/*IntegrationTest.java
+
+
+
+
+
+
+ json
+
+
+
+
+
+
+
+
+
+ UTF-8
+
+
+ 4.12
+ 2.7.5
+
+
+ 3.6.0
+ 2.19.1
+
+
diff --git a/mockito2/src/main/java/com/baeldung/mockito/java8/JobPosition.java b/mockito2/src/main/java/com/baeldung/mockito/java8/JobPosition.java
new file mode 100644
index 0000000000..c7712fa47e
--- /dev/null
+++ b/mockito2/src/main/java/com/baeldung/mockito/java8/JobPosition.java
@@ -0,0 +1,20 @@
+package com.baeldung.mockito.java8;
+
+public class JobPosition {
+ private String title;
+
+ public JobPosition() {}
+
+ public JobPosition(String title) {
+ super();
+ this.title = title;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+}
diff --git a/mockito2/src/main/java/com/baeldung/mockito/java8/JobService.java b/mockito2/src/main/java/com/baeldung/mockito/java8/JobService.java
new file mode 100644
index 0000000000..85a59b18a4
--- /dev/null
+++ b/mockito2/src/main/java/com/baeldung/mockito/java8/JobService.java
@@ -0,0 +1,20 @@
+package com.baeldung.mockito.java8;
+
+import java.util.Optional;
+import java.util.stream.Stream;
+
+public interface JobService {
+ Optional findCurrentJobPosition(Person person);
+
+ default boolean assignJobPosition(Person person, JobPosition jobPosition) {
+ if (!findCurrentJobPosition(person).isPresent()) {
+ person.setCurrentJobPosition(jobPosition);
+
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ Stream listJobs(Person person);
+}
diff --git a/mockito2/src/main/java/com/baeldung/mockito/java8/Person.java b/mockito2/src/main/java/com/baeldung/mockito/java8/Person.java
new file mode 100644
index 0000000000..4f7af49f9d
--- /dev/null
+++ b/mockito2/src/main/java/com/baeldung/mockito/java8/Person.java
@@ -0,0 +1,28 @@
+package com.baeldung.mockito.java8;
+
+public class Person {
+ private String name;
+ private JobPosition currentJobPosition;
+
+ public Person() {}
+
+ public Person(String name) {
+ this.name = name;
+ }
+
+ public JobPosition getCurrentJobPosition() {
+ return currentJobPosition;
+ }
+
+ public void setCurrentJobPosition(JobPosition currentJobPosition) {
+ this.currentJobPosition = currentJobPosition;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
diff --git a/mockito2/src/main/java/com/baeldung/mockito/java8/UnemploymentService.java b/mockito2/src/main/java/com/baeldung/mockito/java8/UnemploymentService.java
new file mode 100644
index 0000000000..5859ab31b0
--- /dev/null
+++ b/mockito2/src/main/java/com/baeldung/mockito/java8/UnemploymentService.java
@@ -0,0 +1,11 @@
+package com.baeldung.mockito.java8;
+
+import java.util.Optional;
+
+public interface UnemploymentService {
+
+ boolean personIsEntitledToUnemploymentSupport(Person person);
+
+ Optional searchJob(Person person, String searchString);
+
+}
diff --git a/mockito2/src/main/java/com/baeldung/mockito/java8/UnemploymentServiceImpl.java b/mockito2/src/main/java/com/baeldung/mockito/java8/UnemploymentServiceImpl.java
new file mode 100644
index 0000000000..6f189b46ea
--- /dev/null
+++ b/mockito2/src/main/java/com/baeldung/mockito/java8/UnemploymentServiceImpl.java
@@ -0,0 +1,26 @@
+package com.baeldung.mockito.java8;
+
+import java.util.Optional;
+import java.util.stream.Stream;
+
+public class UnemploymentServiceImpl implements UnemploymentService {
+ private final JobService jobService;
+
+ public UnemploymentServiceImpl(JobService jobService) {
+ this.jobService = jobService;
+ }
+
+ @Override
+ public boolean personIsEntitledToUnemploymentSupport(Person person) {
+ Optional optional = jobService.findCurrentJobPosition(person);
+
+ return !optional.isPresent();
+ }
+
+ @Override
+ public Optional searchJob(Person person, String searchString) {
+ Stream stream = jobService.listJobs(person);
+
+ return stream.filter((j) -> j.getTitle().contains(searchString)).findFirst();
+ }
+}
diff --git a/mockito2/src/test/java/com/baeldung/mockito/java8/ArgumentMatcherWithLambdaUnitTest.java b/mockito2/src/test/java/com/baeldung/mockito/java8/ArgumentMatcherWithLambdaUnitTest.java
new file mode 100644
index 0000000000..2efac513b7
--- /dev/null
+++ b/mockito2/src/test/java/com/baeldung/mockito/java8/ArgumentMatcherWithLambdaUnitTest.java
@@ -0,0 +1,44 @@
+package com.baeldung.mockito.java8;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.when;
+
+import java.util.Optional;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentMatchers;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+
+public class ArgumentMatcherWithLambdaUnitTest {
+
+ @InjectMocks
+ private UnemploymentServiceImpl unemploymentService;
+
+ @Mock
+ private JobService jobService;
+
+ @Test
+ public void whenPersonWithJob_thenIsNotEntitled() {
+ Person peter = new Person("Peter");
+ Person linda = new Person("Linda");
+
+ JobPosition teacher = new JobPosition("Teacher");
+
+ when(jobService.findCurrentJobPosition(
+ ArgumentMatchers.argThat((p) -> p.getName().equals("Peter")))
+ ).thenReturn(Optional.of(teacher));
+
+ assertTrue(unemploymentService.personIsEntitledToUnemploymentSupport(linda));
+ assertFalse(unemploymentService.personIsEntitledToUnemploymentSupport(peter));
+ }
+
+ @Before
+ public void init() {
+ MockitoAnnotations.initMocks(this);
+ }
+}
diff --git a/mockito2/src/test/java/com/baeldung/mockito/java8/ArgumentMatcherWithoutLambdaUnitTest.java b/mockito2/src/test/java/com/baeldung/mockito/java8/ArgumentMatcherWithoutLambdaUnitTest.java
new file mode 100644
index 0000000000..f4e8fb4cf5
--- /dev/null
+++ b/mockito2/src/test/java/com/baeldung/mockito/java8/ArgumentMatcherWithoutLambdaUnitTest.java
@@ -0,0 +1,55 @@
+package com.baeldung.mockito.java8;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.when;
+
+import java.util.Optional;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentMatchers;
+import org.mockito.InjectMocks;
+import org.mockito.ArgumentMatcher;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+
+public class ArgumentMatcherWithoutLambdaUnitTest {
+ @InjectMocks
+ private UnemploymentServiceImpl unemploymentService;
+
+ @Mock
+ private JobService jobService;
+
+ @Test
+ public void whenPersonWithJob_thenIsNotEntitled() {
+ Person peter = new Person("Peter");
+ Person linda = new Person("Linda");
+
+ JobPosition teacher = new JobPosition("Teacher");
+
+ when(jobService.findCurrentJobPosition(
+ ArgumentMatchers.argThat(new PeterArgumentMatcher()))
+ ).thenReturn(Optional.of(teacher));
+
+ assertTrue(unemploymentService.personIsEntitledToUnemploymentSupport(linda));
+ assertFalse(unemploymentService.personIsEntitledToUnemploymentSupport(peter));
+ }
+
+ private class PeterArgumentMatcher implements ArgumentMatcher {
+ @Override
+ public boolean matches(Person p) {
+
+ if (p.getName().equals("Peter")) {
+ return true;
+ }
+ return false;
+ }
+ }
+
+ @Before
+ public void init() {
+ MockitoAnnotations.initMocks(this);
+ }
+}
diff --git a/mockito2/src/test/java/com/baeldung/mockito/java8/CustomAnswerWithLambdaUnitTest.java b/mockito2/src/test/java/com/baeldung/mockito/java8/CustomAnswerWithLambdaUnitTest.java
new file mode 100644
index 0000000000..eebb86e239
--- /dev/null
+++ b/mockito2/src/test/java/com/baeldung/mockito/java8/CustomAnswerWithLambdaUnitTest.java
@@ -0,0 +1,45 @@
+package com.baeldung.mockito.java8;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.when;
+
+import java.util.stream.Stream;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+public class CustomAnswerWithLambdaUnitTest {
+ @InjectMocks
+ private UnemploymentServiceImpl unemploymentService;
+
+ @Mock
+ private JobService jobService;
+
+ @Test
+ public void whenPersonWithJobHistory_thenSearchReturnsValue() {
+ Person peter = new Person("Peter");
+
+ assertEquals("Teacher", unemploymentService.searchJob(peter, "").get().getTitle());
+ }
+
+ @Test
+ public void whenPersonWithNoJobHistory_thenSearchReturnsEmpty() {
+ Person linda = new Person("Linda");
+
+ assertFalse(unemploymentService.searchJob(linda, "").isPresent());
+ }
+
+ @Before
+ public void init() {
+ MockitoAnnotations.initMocks(this);
+
+ when(jobService.listJobs(any(Person.class))).then((i) -> {
+ return ((Person) i.getArgument(0)).getName().equals("Peter") ? Stream. builder().add(new JobPosition("Teacher")).build() : Stream.empty();
+ });
+ }
+}
diff --git a/mockito2/src/test/java/com/baeldung/mockito/java8/CustomAnswerWithoutLambdaUnitTest.java b/mockito2/src/test/java/com/baeldung/mockito/java8/CustomAnswerWithoutLambdaUnitTest.java
new file mode 100644
index 0000000000..28922bb303
--- /dev/null
+++ b/mockito2/src/test/java/com/baeldung/mockito/java8/CustomAnswerWithoutLambdaUnitTest.java
@@ -0,0 +1,59 @@
+package com.baeldung.mockito.java8;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.when;
+
+import java.util.stream.Stream;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+
+public class CustomAnswerWithoutLambdaUnitTest {
+ @InjectMocks
+ private UnemploymentServiceImpl unemploymentService;
+
+ @Mock
+ private JobService jobService;
+
+ @Test
+ public void whenPersonWithJobHistory_thenSearchReturnsValue() {
+ Person peter = new Person("Peter");
+
+ assertEquals("Teacher", unemploymentService.searchJob(peter, "").get().getTitle());
+ }
+
+ @Test
+ public void whenPersonWithNoJobHistory_thenSearchReturnsEmpty() {
+ Person linda = new Person("Linda");
+
+ assertFalse(unemploymentService.searchJob(linda, "").isPresent());
+ }
+
+ private class PersonAnswer implements Answer> {
+ @Override
+ public Stream answer(InvocationOnMock invocation) throws Throwable {
+ Person person = invocation.getArgument(0);
+
+ if(person.getName().equals("Peter")) {
+ return Stream.builder().add(new JobPosition("Teacher")).build();
+ }
+
+ return Stream.empty();
+ }
+ }
+
+ @Before
+ public void init() {
+ MockitoAnnotations.initMocks(this);
+
+ when(jobService.listJobs(any(Person.class))).then(new PersonAnswer());
+ }
+}
diff --git a/mockito2/src/test/java/com/baeldung/mockito/java8/JobServiceUnitTest.java b/mockito2/src/test/java/com/baeldung/mockito/java8/JobServiceUnitTest.java
new file mode 100644
index 0000000000..9ea5c1db47
--- /dev/null
+++ b/mockito2/src/test/java/com/baeldung/mockito/java8/JobServiceUnitTest.java
@@ -0,0 +1,44 @@
+package com.baeldung.mockito.java8;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.doCallRealMethod;
+import static org.mockito.Mockito.when;
+
+import java.util.Optional;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+
+public class JobServiceUnitTest {
+ @Mock
+ private JobService jobService;
+
+ @Test
+ public void givenDefaultMethod_whenCallRealMethod_thenNoExceptionIsRaised() {
+ Person person = new Person();
+
+ when(jobService.findCurrentJobPosition(person)).thenReturn(Optional.of(new JobPosition()));
+ doCallRealMethod().when(jobService).assignJobPosition(Mockito.any(Person.class), Mockito.any(JobPosition.class));
+
+ assertFalse(jobService.assignJobPosition(person, new JobPosition()));
+ }
+
+ @Test
+ public void givenReturnIsOfTypeOptional_whenDefaultValueIsReturned_thenValueIsEmpty() {
+ Person person = new Person();
+
+ when(jobService.findCurrentJobPosition(person)).thenReturn(Optional.empty());
+ doCallRealMethod().when(jobService).assignJobPosition(Mockito.any(Person.class), Mockito.any(JobPosition.class));
+
+ assertTrue(jobService.assignJobPosition(person, new JobPosition()));
+ }
+
+ @Before
+ public void init() {
+ MockitoAnnotations.initMocks(this);
+ }
+}
diff --git a/mockito2/src/test/java/com/baeldung/mockito/java8/UnemploymentServiceImplUnitTest.java b/mockito2/src/test/java/com/baeldung/mockito/java8/UnemploymentServiceImplUnitTest.java
new file mode 100644
index 0000000000..b3b71e5bf9
--- /dev/null
+++ b/mockito2/src/test/java/com/baeldung/mockito/java8/UnemploymentServiceImplUnitTest.java
@@ -0,0 +1,62 @@
+package com.baeldung.mockito.java8;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.when;
+
+import java.util.Optional;
+import java.util.stream.Stream;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+public class UnemploymentServiceImplUnitTest {
+ @Mock
+ private JobService jobService;
+
+ @InjectMocks
+ private UnemploymentServiceImpl unemploymentService;
+
+ @Test
+ public void givenReturnIsOfTypeOptional_whenMocked_thenValueIsEmpty() {
+ Person person = new Person();
+
+ when(jobService.findCurrentJobPosition(any(Person.class))).thenReturn(Optional.empty());
+
+ assertTrue(unemploymentService.personIsEntitledToUnemploymentSupport(person));
+ }
+
+ @Test
+ public void givenReturnIsOfTypeOptional_whenDefaultValueIsReturned_thenValueIsEmpty() {
+ Person person = new Person();
+
+ // This will fail when Mockito 1 is used
+ assertTrue(unemploymentService.personIsEntitledToUnemploymentSupport(person));
+ }
+
+ @Test
+ public void givenReturnIsOfTypeStream_whenMocked_thenValueIsEmpty() {
+ Person person = new Person();
+
+ when(jobService.listJobs(any(Person.class))).thenReturn(Stream.empty());
+
+ assertFalse(unemploymentService.searchJob(person, "").isPresent());
+ }
+
+ @Test
+ public void givenReturnIsOfTypeStream_whenDefaultValueIsReturned_thenValueIsEmpty() {
+ Person person = new Person();
+
+ // This will fail when Mockito 1 is used
+ assertFalse(unemploymentService.searchJob(person, "").isPresent());
+ }
+
+ @Before
+ public void init() {
+ MockitoAnnotations.initMocks(this);
+ }
+}
diff --git a/pom.xml b/pom.xml
index a392c142d0..16dc0a50d0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -84,6 +84,7 @@
metrics
mesos-marathon
mockito
+ mockito2
mocks
orika