Mockito works on the mock, stub, and verify methodology. We need to define mock and stub first before verification.
Good coding practice is to keep code clean, simple, and precise.
stub and mock only those fields and instances which are begin used while testing, unnecessary code, mock and stubs overall increase complexity, memory utilization of the test case execution, and is time-consuming as well.
By default there is no way to enforce developer to write clean code, it all depends on the coding practice followed. Mockito provides Strictness
enum rules which need to be set in @MockitoSettings
that enforce developers to remove unnecessary stubbing, unwanted mocks, and write clean code which eventually results in better productivity.
@MockitoSettings internally calls @ExtendWith
Lenient Strictness
Strictness#LENIENT
doesn't enforce developer to write clean code, unnecessary mock and stubbing are allowed. It overall decreases the performance of application execution. it's advised not to use Strictness#LENIENT
but to use Strictness#STRICT_STUBS
.
Strictness#LENIENT was the default behaviour of Mockito 1.x.
In below code
when(appleService.saveApple("Macintosh")).thenReturn("i eat apple")
is an unnecessary stub that has never been used, but compile will not throw any exception or warning.
package com.example.mokito3.sujan;
public class AppleService {
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.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.mockito.junit.jupiter.MockitoSettings;
import org.mockito.quality.Strictness;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@MockitoSettings(strictness = Strictness.LENIENT)
public class AppleServiceTest {
@Mock
private AppleService appleService;
@Test
void saveAppleFinalClassMockTest() {
/* Unnecessary stub */
when(appleService.saveApple("Macintosh")).thenReturn("i eat apple");
when(appleService.saveApple("Fuji")).thenReturn("i eat apple");
String apple = appleService.saveApple("Fuji");
verify(appleService).saveApple("Fuji");
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()
}
Warn Strictness
Strictness#WARN
doesn't enforce developers to write clean code. Unnecessary mock and stubbing are allowed but it will show extra warning on the console which mocks or stub is not being used in the test case and can be safely removed and improves debuggability. It overall decreases the performance of application execution. it's advised not to use Strictness#WARN
but to use Strictness#STRICT_STUBS
because console warnings are ignored most of the time.
Strictness#WARN is the default behaviour of Mockito 2.x.
In below code
when(appleService.saveApple("Macintosh")).thenReturn("i eat apple")
is an unnecessary stub that has never been used, so compile will show a warning on console.
package com.example.mokito3.sujan;
public class AppleService {
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.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.mockito.junit.jupiter.MockitoSettings;
import org.mockito.quality.Strictness;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@MockitoSettings(strictness = Strictness.WARN)
public class AppleServiceTest {
@Mock
private AppleService appleService;
@Test
void saveAppleFinalClassMockTest() {
/* Unnecessary stub */
when(appleService.saveApple("Macintosh")).thenReturn("i eat apple");
when(appleService.saveApple("Fuji")).thenReturn("i eat apple");
String apple = appleService.saveApple("Fuji");
verify(appleService).saveApple("Fuji");
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()
}
Strict Stubs Strictness
Strictness#STRICT_STUBS
enforce developer to write clean code, unnecessary and unused mock and stubbing are not allowed. It reduces code duplication, improves debuggability hence overall increases the performance and productivity of the application. it's highly recommended to use Strictness#STRICT_STUBS
.
Strictness#STRICT_STUBS will be the default behaviour of Mockito 3.x. onwards.
In below code
when(appleService.saveApple("Macintosh")).thenReturn("i eat apple")
is an unnecessary stub that has never been used, so compile throw UnnecessaryStubbingException
.
package com.example.mokito3.sujan;
public class AppleService {
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.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.mockito.junit.jupiter.MockitoSettings;
import org.mockito.quality.Strictness;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@MockitoSettings(strictness = Strictness.STRICT_STUBS)
public class AppleServiceTest {
@Mock
private AppleService appleService;
@Test
void saveAppleFinalClassMockTest() {
/* Unnecessary stub */
when(appleService.saveApple("Macintosh")).thenReturn("i eat apple");
when(appleService.saveApple("Fuji")).thenReturn("i eat apple");
String apple = appleService.saveApple("Fuji");
verify(appleService).saveApple("Fuji");
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()
}