Code flow is like a behavior for example if the user given
options A and B, when
user opts for A then
C should be output or if opts for B then
D respectively.
from above, we can deduce the user's behavior and create a test case to mimic user behavior, called Behavior Driven Development or BDD.
In order to create a BDD test case, Mockito provides us a new class BDDMockito
with given
, when
and then
methods.
Mockito#when
andBDDMockito#given
are technically same.
Mockito#when
is already present and provides the exact same functionality that BDDMockito#given
provides. if required we can use Mockito#when
as well. Initially, the Mockito framework was more stub oriented hence term and vocabulary when was used to depict the stubs. so in technical terms test cases were created with when ... then ... style
Nowadays test cases have evolved from basic input and output to Behavior Driven Development or BDD, which is more focused on human behavior than technical terms. To depict human behavior vocabulary terms are an update to given ... then ... style.
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.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.BDDMockito.given;
@ExtendWith(MockitoExtension.class)
public class AppleServiceTest {
@Mock
private AppleService appleService;
@Test
void saveAppleWithoutMockTest() {
// given
given(appleService.saveApple("Macintosh")).willReturn("i eat apple");
// when
String macApple = appleService.saveApple("Macintosh");
// then
assertEquals("i eat apple", macApple);
}
}
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#when vs BDDMockito#given
BDDMockito
provides new ways to write test cases in given ... then ... style and help in Behavior Driven Development or BDD, but it doesn't mean we can use Mockito traditional way. In fact, there is very little difference between Mockito#when
vs BDDMockito#given
.
package com.example.mokito3.sujan;
public class AppleService {
public String saveApple(String apple) {
String appleString = "i love " + apple + " apple";
return appleString;
}
}
Mockito#when | BDDMockito#given |
---|---|
|
|
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()
}
For BDD or to mimic human vehaviour, we can use Inorder
interface.
package com.example.mokito3.sujan;
public class AppleService {
public String saveApple(String apple) {
String appleString = "i love " + apple + " apple";
return appleString;
}
public String haveApple(int appleCount) {
String appleString = "i have " + appleCount + " apple";
return appleString;
}
public String eatApple(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.BDDMockito.then;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.times;
@ExtendWith(MockitoExtension.class)
public class AppleServiceTest {
@Mock
private AppleService appleService;
@Test
void appleMockTest() {
InOrder inOrder = inOrder(appleService);
appleService.saveApple("Macintosh");
appleService.haveApple(2);
appleService.eatApple("Macintosh");
appleService.eatApple("Macintosh");
then(appleService).should(inOrder).saveApple("Macintosh");
then(appleService).should(inOrder).haveApple(2);
then(appleService).should(inOrder, times(2)).eatApple("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()
}
BDD when ... then ... style can be used with Exceptions as well.
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.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.BDDMockito.willThrow;
@ExtendWith(MockitoExtension.class)
public class AppleServiceTest {
@Mock
private AppleService appleService;
@Test
void saveAppleWithoutMockTest() {
//given
willThrow(new IllegalArgumentException()).given(appleService).saveApple(null);
// when // then
assertThrows(IllegalArgumentException.class, () -> appleService.saveApple(null));
}
}
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()
}