Issue
I have a method in service layer for saving an item to database. This method first checks if there is an item with the same name in database. If there is, then it throws an exception with a message, if there is not then it just saves the new item. Here is the code;
public TodoList saveTodoList(TodoList todoList) {
List<TodoList> match = StreamSupport.stream(getAllTodoLists().spliterator(), false)
.filter(list -> list.getName().equals(todoList.getName()))
.collect(Collectors.toList());
if (match.size() > 0)
throw new ExistingDataException("Todo List already exists!");
else
return todoListRepository.save(todoList);
}
I am trying to learn testing with JUnit 5 and Mockito and I am a bit confused about what to test in general. How many tests should I write for this method? Do I need to test stream(I don't even know how)? How can you decide what to test in a method?
Edit: Here is my test class and test methods for the save method;
@ExtendWith(MockitoExtension.class)
class TodoListServiceTest {
@Mock
private ITodoListRepository todoListRepository;
@InjectMocks
private TodoListService todoListService;
@Test
@DisplayName("Should save the list to the repository")
public void whenGivenTodoListDoesNotExistInDatabase_ThenSaveNewList() {
TodoList mockList = mock(TodoList.class);
mockList.setId(1);
mockList.setName("List 1");
when(todoListRepository.save(any(TodoList.class))).thenReturn(mockList);
TodoList actual = todoListService.saveTodoList(mockList);
assertEquals(mockList.getId(), actual.getId());
assertEquals(mockList.getName(), actual.getName());
}
@Test
@DisplayName("Should throw exception if there is a list with given item's name")
public void shouldThrowExistingDataException_IfThereIsAList_WithTheSameName() {
TodoList mockList = mock(TodoList.class);
mockList.setId(1);
mockList.setName("List 1");
Throwable actualException = assertThrows(ExistingDataException.class,
() -> {
todoListService.saveTodoList(mockList);
});
assertTrue(actualException.getMessage().contains("Todo List already exists!"));
}
Solution
I will try to answer some of the questions that you have asked:
How many tests should I write for this method?: Essentially while writing test cases for a function or piece of code, there is no limit on how many test cases you should write. Generally you try to test atleast 1 positive flow and 1 negative flow. If your piece of code has many edge cases, then probably check those as well.
Do I need to test stream(I don't even know how)? : No. Stream is inbuilt java feature, you don't test inbuilt features. You just test your logic.
How can you decide what to test in a method?: As I mentioned earlier, you generally test positive flows and negative flows including any edge cases. For the above function it seems you have 1 positive and 1 negative flow. Your positive scenario could be where you expect value to not be present in your database and successfully store the data and your negative scenario can be when that data is already present you throw an exception. These are two minimum test cases you should write.
Answered By - Ujwal Kumar
Answer Checked By - David Goodson (JavaFixing Volunteer)