Mockito doReturn()
is equivalent to Mockito when
, it is used to stub the void method.
Mockito#when recommended over Mockito#doReturn for stubbing especially when stubbing consecutive calls because it is argument type-safe and more readable.
package com.example.mokito3.sujan;
public class AppleService {
public String processApple(String appleName) {
String appleString = "I love " + appleName + " Apple";
return appleString;
}
}
package com.example.mokito3.sujan;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
@ExtendWith(MockitoExtension.class)
public class AppleServiceTest {
@Mock
private AppleService appleService;
@Test
void saveAppleWithStaticMockTest() {
AppleService appleService = mock(AppleService.class);
doReturn("i eat apple").when(appleService).processApple("Macintosh");
String apple = appleService.processApple("Macintosh");
Assertions.assertEquals("i eat apple", apple);
}
@Test
void saveAppleWithAnnotationMockTest() {
doReturn("i eat apple").when(appleService).processApple("Macintosh");
String apple = appleService.processApple("Macintosh");
Assertions.assertEquals("i eat apple", apple);
}
}
plugins {
id 'java'
}
group 'org.example'
version '1.0-SNAPSHOT'
repositories { jcenter() }
dependencies {
testImplementation('org.junit.jupiter:junit-jupiter:5.6.2')
testCompile 'org.mockito:mockito-junit-jupiter:3.4.4'
}
test {
useJUnitPlatform()
}
Stubber doReturn Continues stub
doReturn
method has overloaded constructor which allows to configure continues stub.
package com.example.mokito3.sujan;
public class AppleService {
public String processApple(String appleName) {
String appleString = "I love " + appleName + " Apple";
return appleString;
}
}
package com.example.mokito3.sujan;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
@ExtendWith(MockitoExtension.class)
public class AppleServiceTest {
@Mock
private AppleService appleService;
@Test
void saveAppleWithStaticMockTest() {
AppleService appleService = mock(AppleService.class);
doReturn("i eat apple", "i have apple").when(appleService).processApple("Macintosh");
String appleCase1 = appleService.processApple("Macintosh");
String appleCase2 = appleService.processApple("Macintosh");
Assertions.assertEquals("i eat apple", appleCase1);
Assertions.assertEquals("i have apple", appleCase2);
}
@Test
void saveAppleWithAnnotationMockTest() {
doReturn("i eat apple", "i have apple").when(appleService).processApple("Macintosh");
String appleCase1 = appleService.processApple("Macintosh");
String appleCase2 = appleService.processApple("Macintosh");
Assertions.assertEquals("i eat apple", appleCase1);
Assertions.assertEquals("i have apple", appleCase2);
}
}
plugins {
id 'java'
}
group 'org.example'
version '1.0-SNAPSHOT'
repositories { jcenter() }
dependencies {
testImplementation('org.junit.jupiter:junit-jupiter:5.6.2')
testCompile 'org.mockito:mockito-junit-jupiter:3.4.4'
}
test {
useJUnitPlatform()
}
Overriding Exception Stub
Although not recomemded but there might be a scnerio to override privious stub. In normal stubbing override stub will take over except exception stub.
These scnerio is very rare and should not occur, overriding stubbing is a code smell and must be avoided at any cost.
package com.example.mokito3.sujan;
public class AppleService {
public String processApple(String appleName) {
String appleString = "I love " + appleName + " Apple";
return appleString;
}
}
package com.example.mokito3.sujan;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
public class AppleServiceTest {
@Mock
private AppleService appleService;
@Test
void saveAppleWithStaticMockTest() {
AppleService appleService = mock(AppleService.class);
when(appleService.processApple("Macintosh")).thenThrow(new RuntimeException("exception will be thrown"));
when(appleService.processApple("Macintosh")).thenReturn("i eat apple");
String apple = appleService.processApple("Macintosh");
Assertions.assertEquals("i eat apple", apple);
}
@Test
void saveAppleWithAnnotationMockTest() {
when(appleService.processApple("Macintosh")).thenThrow(new RuntimeException("exception will be thrown"));
when(appleService.processApple("Macintosh")).thenReturn("i eat apple");
String apple = appleService.processApple("Macintosh");
Assertions.assertEquals("i eat apple", apple);
}
}
plugins {
id 'java'
}
group 'org.example'
version '1.0-SNAPSHOT'
repositories { jcenter() }
dependencies {
testImplementation('org.junit.jupiter:junit-jupiter:5.6.2')
testCompile 'org.mockito:mockito-junit-jupiter:3.4.4'
}
test {
useJUnitPlatform()
}
To correctly override exception stub doReturn
method must be used and to avoid UnnecessaryStubbingException
because of multiple stubbing for same input parameter Strictness#LENIENT
must be configured.
package com.example.mokito3.sujan;
public class AppleService {
public String processApple(String appleName) {
String appleString = "I love " + appleName + " Apple";
return appleString;
}
}
package com.example.mokito3.sujan;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoSettings;
import org.mockito.quality.Strictness;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@MockitoSettings(strictness = Strictness.LENIENT)
public class AppleServiceTest {
@Mock
private AppleService appleService;
@Test
void saveAppleWithStaticMockTest() {
AppleService appleService = mock(AppleService.class);
when(appleService.processApple("Macintosh")).thenThrow(new RuntimeException("exception will be thrown"));
doReturn("i eat apple").when(appleService).processApple("Macintosh");
String apple = appleService.processApple("Macintosh");
Assertions.assertEquals("i eat apple", apple);
}
@Test
void saveAppleWithAnnotationMockTest() {
when(appleService.processApple("Macintosh")).thenThrow(new RuntimeException("exception will be thrown"));
doReturn("i eat apple").when(appleService).processApple("Macintosh");
String apple = appleService.processApple("Macintosh");
Assertions.assertEquals("i eat apple", apple);
}
}
plugins {
id 'java'
}
group 'org.example'
version '1.0-SNAPSHOT'
repositories { jcenter() }
dependencies {
testImplementation('org.junit.jupiter:junit-jupiter:5.6.2')
testCompile 'org.mockito:mockito-junit-jupiter:3.4.4'
}
test {
useJUnitPlatform()
}
Spy side effects
Spy calls the real method, but calling a real method on spy brings its side effects.
in below example a spy
of LinkedList
has been created, so appleList#get(0)
will actuly call the real method, but because LinkedList
is still empty so IndexOutOfBoundsException
will be thrown.
package com.example.mokito3.sujan;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.junit.jupiter.MockitoExtension;
import java.util.LinkedList;
import java.util.List;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
public class AppleServiceTest {
@Test
void saveAppleWithStaticMockTest() {
List<String> appleList = spy(LinkedList.class);
when(appleList.get(0)).thenReturn("Macintosh");
String apple = appleList.get(0);
Assertions.assertEquals("Macintosh", apple);
}
}
to properly avoid side effect of calling a real method on spy use doReturn.
package com.example.mokito3.sujan;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.junit.jupiter.MockitoExtension;
import java.util.LinkedList;
import java.util.List;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
@ExtendWith(MockitoExtension.class)
public class AppleServiceTest {
@Test
void saveAppleWithStaticMockTest() {
List<String> appleList = spy(LinkedList.class);
doReturn("Macintosh").when(appleList).get(0);
String apple = appleList.get(0);
Assertions.assertEquals("Macintosh", apple);
}
}