Issue
I ran into a unit test like this
@InjectMocks
private PersonService personService;
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private Person person;
@Before
void init() {
when(person.getFirstName()).thenReturn("John");
when(person.getLastName()).thenReturn("Doe");
when(person.getBirthDate()).thenReturn("1990-01-01"); //sorry about the date string, just an example
}
@Test
void shouldReturnCorrectAge() {
Integer age = personService.getPersonAge(person);
assertEquals(32, age);
}
Why is stubbing done? is there any difference if the value is just directly assigned like in the next code below, is one a better way than the other?
Person person;
@Before
void init() {
person = new Person();
person.setFirstName("John");
person.setLastName("Doe");
person.setBirthDate("1990-01-01"); //sorry about the date string, just an example
}
@Test
void shouldReturnCorrectAge() {
Integer age = personService.getPersonAge(person);
assertEquals(32, age);
}
Solution
I think the second option is better in this example.
Setting up stubs for simple getters like this is not really required - you should usually leave mocking for cases where there are external dependency/class calls, not on POJOs containing simple values. Mocks help with verifying interactions and tracking the amount of times that a method has been called (for example, if you would want to absolutely make sure that some NotificationService method has been called when some condition is fulfilled in a unit test).
In some cases you can easily set the values in an external service class like in the second example, but you should still use mocks as you are testing the functionality of a single class - mocks help you set up tests in a way that says GIVEN that some external service/method returns X, do Y. The responsibility of verifying the other class' output is dependent on that class' own unit tests.
Answered By - Nauris Utnāns
Answer Checked By - Dawn Plyler (JavaFixing Volunteer)