Word definitions taken from:
https://stackoverflow.com/questions/346372/whats-the-difference-between-faking-mocking-and-stubbing
- Stub - an object that contains predefined answers to methods
- Mock - an object made to satisfy the expected outcome, just like a dummy
- Fake - an object with a minimum necessary implementation/ return value for a test
Mocking a class
SomeClass someClass = mock(SomeClass.class);
// this creates a mock of a class. but it won't perform any responsibility of that class
Sample class for this tutorial, 'MyClass'
class MyClass {
public MyClass(SomeService someService, AnotherClass anotherClass) {
this.someService = someService:
this.anotherClass = anotherClass:
}
}
We can easily mock these kind of constructor parameters using @Mock annotation
@Mock
SomeService someService;
@Mock
AnotherClass anotherClass;
MyClass myClass;
private initTests() {
myClass = new MyClass(someService, anotherClass);
}
If the class MyClass contains a function defined below,
public String getStudentName () {
SomeClass someClass = someService.getThatObject();
Student student = someClass.getStudent();
return student.getName();
}
We can simply test it like below (this is just to understand the concepts, and not the only possible way to test)
@Test
function testGivenWhenThenSomeTestFunctionName () {
SomeService someService = mock(SomeService.class);
SomeClass someClass = mock(SomeClass.class);
Student student = mock(Student.class);
when( someService.getThatObject() ).thenReturn(someClass);
when( someClass.getStudent() ).thenReturn(student);
when( student.getName() ).thenReturn("expectedStringValue");
String result = myClass.getStudentName();
assertEquals(result, "expectedStringValue");
}
we can test the same function like below too, without mocking intermediate results
@Test
function testGivenWhenThenSomeTestFunctionName () {
SomeService someService = mock(SomeService.class);
SomeClass someClass = mock(SomeClass.class);
when( someService.getThatObject() ).thenReturn(someClass);
when( someClass.getStudent() ).thenReturn(student);
when( someClass.getStudent().getName() ).thenReturn("expectedStringValue");
String result = myClass.getStudentName();
assertEquals(result, "expectedStringValue");
}even we can use deep stubs to test the above function
@Test
// @TODO: verify this working
function testGivenWhenThenSomeTestFunctionName () {
SomeService someService = mock(SomeService.class);
Student student = mock(Student.class, Mockito.RETURNS_DEEP_STUBS);
SomeClass someClass = mock(SomeClass.class, Mockito.RETURNS_DEEP_STUBS);
student.setName("expectedStringValue");
someClass.setStudent(student);
when( someService.getThatObject() ).thenReturn(someClass);
String result = myClass.getStudentNam();
assertEquals(result, "expectedStringValue");
}
@TODO:
catching expected exceptions
@TODO:
calling real implementation
@TODO:
stub private/protected methods