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);
}
CodePudding user response:
In the first scenario you are mocking the method. That way if the personService.getPersonAge() makes a call to any of those person methods it will return the selected value
In the second scenario, you are creating a Person object. In this case, as you pass the person parameter, you know what is going to return.
But what if instead of a getter you had a DB operation? In that case you shouldn't access the DB in a test, so you mock the DB methods in the service to return your desired value.
CodePudding user response:
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.