Mockito#verify
provides us a great way to validate the mock instance call with the desired parameter and its response, but what if we not only want to validate the request and response of mock instance but the order of invocation as well. For this Mockito Provides us InOrder
interface.
package com.example.mokito3.sujan;
public class AppleService {
public String saveApple(String apple) {
String appleString = "i love " + apple + " apple";
return appleString;
}
}
package com.example.mokito3.sujan;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
@ExtendWith(MockitoExtension.class)
public class AppleServiceTest {
@Mock
private AppleService appleService;
@Test
void saveAppleWithStaticMockTest() {
AppleService appleService = mock(AppleService.class);
InOrder inOrder = inOrder(appleService);
appleService.saveApple("Macintosh");
appleService.saveApple("Fuji");
inOrder.verify(appleService).saveApple("Macintosh");
inOrder.verify(appleService).saveApple("Fuji");
}
@Test
void saveAppleWithAnnotationMockTest() {
InOrder inOrder = inOrder(appleService);
appleService.saveApple("Macintosh");
appleService.saveApple("Fuji");
inOrder.verify(appleService).saveApple("Macintosh");
inOrder.verify(appleService).saveApple("Fuji");
}
}
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()
}
InOrder with VerificationMode
We need to verify the order of interaction with the mock instance, but we have the same method call with the same parameter, one way is to use multiple InOrder#verify
method, or the better way is to use VerificationMode#times
.
All the methods of VerificationMode#times
can be used with InOrder#verify
.
- times(count)
- never()
- atLeastOnce()
- atLeast(count)
- atMost(count)
- only
package com.example.mokito3.sujan;
public class AppleService {
public String saveApple(String apple) {
String appleString = "i love " + apple + " apple";
return appleString;
}
}
package com.example.mokito3.sujan;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
@ExtendWith(MockitoExtension.class)
public class AppleServiceTest {
@Mock
private AppleService saveAppleService;
@Test
void saveAppleWithStaticMockTest() {
AppleService saveAppleService = mock(AppleService.class);
InOrder inOrder = inOrder(saveAppleService);
saveAppleService.saveApple("Macintosh");
saveAppleService.saveApple("Macintosh");
inOrder.verify(saveAppleService, times(2)).saveApple("Macintosh");
}
@Test
void saveAppleWithAnnotationMockTest() {
InOrder inOrder = inOrder(saveAppleService);
saveAppleService.saveApple("Macintosh");
saveAppleService.saveApple("Macintosh");
inOrder.verify(saveAppleService, times(2)).saveApple("Macintosh");
}
}
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()
}
InOrder for multiple method
A mock instance will have multiple methods, we can use Inorder interface to validate multiple interactions with the mock instance for multiple methods as well.
package com.example.mokito3.sujan;
public class AppleService {
public String saveApple(String apple) {
String appleString = "i love " + apple + " apple";
return appleString;
}
public String getApple(String apple) {
String appleString = "i eat " + apple + " apple";
return appleString;
}
}
package com.example.mokito3.sujan;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
@ExtendWith(MockitoExtension.class)
public class AppleServiceTest {
@Mock
private AppleService appleService;
@Test
void saveAppleWithStaticMockTest() {
AppleService appleService = mock(AppleService.class);
InOrder inOrder = inOrder(appleService);
appleService.saveApple("Macintosh");
appleService.getApple("Macintosh");
inOrder.verify(appleService).saveApple("Macintosh");
inOrder.verify(appleService).getApple("Macintosh");
}
@Test
void saveAppleWithAnnotationMockTest() {
InOrder inOrder = inOrder(appleService);
appleService.saveApple("Macintosh");
appleService.getApple("Macintosh");
inOrder.verify(appleService).saveApple("Macintosh");
inOrder.verify(appleService).getApple("Macintosh");
}
}
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()
}
InOrder Short Hand Notation
Inorder is very flexible in terms of validating orders of mock instance interaction. It can be used with multiple classes as well, but creating multiple Inorder instances of mock objects will be boilerplate code, to avoid this, Instance interface support shorthand notation as well. we can pass multiple mock instances in inorder at a time.
package com.example.mokito3.sujan;
public class GetAppleService {
public String getApple(String apple) {
String appleString = "i eat " + apple + " apple";
return appleString;
}
}
package com.example.mokito3.sujan;
public class SaveAppleService {
public String saveApple(String apple) {
String appleString = "i love " + apple + " apple";
return appleString;
}
}
package com.example.mokito3.sujan;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
@ExtendWith(MockitoExtension.class)
public class AppleServiceTest {
@Mock
private SaveAppleService saveAppleService;
@Mock
private GetAppleService getAppleService;
@Test
void saveAppleWithStaticMockTest() {
SaveAppleService saveAppleService = mock(SaveAppleService.class);
GetAppleService getAppleService = mock(GetAppleService.class);
InOrder inOrder = inOrder(saveAppleService, getAppleService);
saveAppleService.saveApple("Macintosh");
getAppleService.getApple("Macintosh");
inOrder.verify(saveAppleService).saveApple("Macintosh");
inOrder.verify(getAppleService).getApple("Macintosh");
}
@Test
void saveAppleWithAnnotationMockTest() {
InOrder inOrder = inOrder(saveAppleService, getAppleService);
saveAppleService.saveApple("Macintosh");
getAppleService.getApple("Macintosh");
inOrder.verify(saveAppleService).saveApple("Macintosh");
inOrder.verify(getAppleService).getApple("Macintosh");
}
}
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()
}
InOrder VerifyNoMoreInteractions
InOrder
verifies the order of interaction and execution of the mock instance. Once all interactions have been verified, InOrder
provides us InOrder#verifyNoMoreInteractions
to make sure that there is no more interaction with the mock instance.
verifies if mocks have any unverified interaction.
InOrder#verifyNoMoreInteractions
is used after all verifications to make sure that nothing else was invoked on mocks.
package com.example.mokito3.sujan;
public class AppleService {
public String saveApple(String apple) {
String appleString = "i love " + apple + " apple";
return appleString;
}
public String getApple(String apple) {
String appleString = "i eat " + apple + " apple";
return appleString;
}
}
package com.example.mokito3.sujan;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import static org.mockito.Mockito.inOrder;
@ExtendWith(MockitoExtension.class)
public class AppleServiceTest {
@Mock
private AppleService appleService;
@Test
void inOrderVerifyNoMoreInteractions() {
InOrder inOrder = inOrder(appleService);
appleService.saveApple("Macintosh");
appleService.getApple("Macintosh");
inOrder.verify(appleService).saveApple("Macintosh");
inOrder.verify(appleService).getApple("Macintosh");
inOrder.verifyNoMoreInteractions();
}
}
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()
}
its not recomeneded to use verifyNoMoreInteractions
in every test method. Use only when it's relevant. Abusing will leads to overspecified, less maintainable tests.
InOrder#verifyNoMoreInteractions vs Mockito#verifyNoMoreInteractions
Mockito
provides Mockito#verifyNoMoreInteractions
and Inorder
also provides InOrder#verifyNoMoreInteractions
method to validate that there is no more interaction with the mock intance, but there is significant difference between them.
InOrder#verifyNoMoreInteractions is different then Mockito#verifyNoMoreInteractions
package com.example.mokito3.sujan;
public class AppleService {
public String saveApple(String apple) {
String appleString = "i love " + apple + " apple";
return appleString;
}
public String getApple(String apple) {
String appleString = "i eat " + apple + " apple";
return appleString;
}
}
package com.example.mokito3.sujan;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
import static org.mockito.Mockito.inOrder;
@ExtendWith(MockitoExtension.class)
public class AppleServiceTest {
@Mock
private AppleService appleService;
@Test
void inOrderVerifyNoMoreInteractions() {
InOrder inOrder = inOrder(appleService);
appleService.saveApple("Macintosh");
appleService.getApple("Macintosh");
inOrder.verify(appleService).saveApple("Macintosh");
inOrder.verify(appleService).getApple("Macintosh");
inOrder.verifyNoMoreInteractions();
}
@Test
void mockitoVerifyNoMoreInteractions() {
appleService.saveApple("Macintosh");
appleService.getApple("Macintosh");
Mockito.verify(appleService).saveApple("Macintosh");
Mockito.verify(appleService).getApple("Macintosh");
Mockito.verifyNoMoreInteractions(appleService);
}
}
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()
}
Mockito#verifyNoMoreInteractions
is make sure that all the interactions are verified which can be in any order where as inOrder#verifyNoMoreInteractions
make sure that interactions and order of inteactions both must be in order.
package com.example.mokito3.sujan;
public class AppleService {
public String saveApple(String apple) {
String appleString = "i love " + apple + " apple";
return appleString;
}
public String getApple(String apple) {
String appleString = "i eat " + apple + " apple";
return appleString;
}
}
package com.example.mokito3.sujan;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
import static org.mockito.Mockito.inOrder;
@ExtendWith(MockitoExtension.class)
public class AppleServiceTest {
@Mock
private AppleService appleService;
@Test
void inOrderVerifyNoMoreInteractions() {
InOrder inOrder = inOrder(appleService);
appleService.saveApple("Macintosh");
appleService.getApple("Macintosh");
inOrder.verify(appleService).getApple("Macintosh");
inOrder.verify(appleService).saveApple("Macintosh");
inOrder.verifyNoMoreInteractions();
}
@Test
void mockitoVerifyNoMoreInteractions() {
appleService.saveApple("Macintosh");
appleService.getApple("Macintosh");
Mockito.verify(appleService).getApple("Macintosh");
Mockito.verify(appleService).saveApple("Macintosh");
Mockito.verifyNoMoreInteractions(appleService);
}
}
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()
}