Let's assume that I have two classes:
the TodoRepository
is a simple CRUD Repository:
public interface TodoRepository extends CrudRepository<T, ID> {
}
the TodoService
is just a class which calls this Repository:
@Service
public class TodoService{
private final TodoRepository todoRepository;
@Autowired
public TodoService(TodoRepository todoRepository) {
this.todoRepository = todoRepository;
}
public void createTodo(Todo todo) {
todoRepository.save(todo);
}
}
Should I bother testing the service layer?
Edit:
Thanks to the explanation from @Dherik. I created a test class which looks like:
Note: I am using JUnit5, Mockito and Spring framework
@ExtendWith(SpringExtension.class)
class TodoServiceTest {
@MockBean
private TodoRepository todoRepository;
private TodoService todoService;
@BeforeEach
void setUp() {
todoService = new TodoService(todoRepository);
}
@AfterEach
void tearDown() {
clearInvocations(tanklevelRepository);
}
@Test
public void createTodo() {
todoService.createTodo(new Todo());
// verify if the save method is called when createTodo is called too
verify(todoRepository, times(1)).save(any(Todo.class));
}
}
Yes, it's important.
Even now being a very simple class, maybe some developer on the future could add some weird condition on this method createTodo
that the Todo
is not saved anymore.
If you write a test for the actual method to verify if the save
is called, the developer will be advised about the situation if he makes some change that affect the Todo
save.
See a pseudo test example:
@Test
public void createTodo() {
TodoRepository todoRepository = mock(TodoRepository.class);
TodoService todoService = new TodoService(todoRepository);
todoService.createTodo(new Todo());
// verify if the save method is called when createTodo is called too
verify(todoRepository, times(1)).save(any(Todo.class));
}
I've seen this kind of thing tested with Junit using a Mock framework and injecting a mock repo into the service, then checking the mock repo was called. That seems really pointless to me as the test knows too much about the implementation. If you change the implementation you have to rewrite the test, so it's no use for refactoring.
I would test this kind of thing with an integration test that treated the app like a black box. i.e. start the app, trigger whatever creates a todo and check that it was created. I'd probably use cucumber-jvm and have a scenario with a step to create a todo and another to retrieve it.
I think you should create tests that
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With