1

I'm developing a project. This project has a repository (UserRepository) which is referenced by other parts of the project, I want to know if I have to test the repository method each time it is referenced: For example, the method (repository.save()) is used in more parts of the project, does it have to be tested each time?

My service:

@Transactional
public UpdateUserDTO update(UpdateUserDTO body) throws JsonMappingException {

    User entity = repository.findByCpfCnpj(body.cpfCnpj()).orElseThrow(
            () -> new EntityNotFoundException("ENTITY NOT FOUND"));

    User userUpdated = mapper.updateValue(entity, body);
    repository.save(userUpdated);
    return mapper.convertValue(userUpdated, UpdateUserDTO.class);
}

My tests:

@Test
public void register_WithInvalidData_ReturnsThrowsException() {

    var invalidUser = UserConstants.getInvalidUser();

    assertThatThrownBy(() -> repository.save(invalidUser)).isInstanceOf(RuntimeException.class);
}

@Test
public void login_WithInvalidData_ReturnsThrowsException() {

    assertThatThrownBy(() -> repository.save(new User())).isInstanceOf(RuntimeException.class);
}
1
  • 1
    A test should invoke your code - the update method in this example. A test could also verify save was invoked. But asserting save throws is testing Spring, not your code.
    – Andrew S
    Commented Jul 2 at 13:10

2 Answers 2

0

I think that as far as the testing is concerned, it is not required to test the repository method each time it is referenced. In this case to get full code coverage you can create a mock repository and use stub for required method calls in the update method test.

0

Make sure your test methods each have a clear purpose for what they're testing, and consider the testing pyramid here.

With a unit test or narrow system test, you should be able to test that repository.save() is behaving correctly including in edge cases and corner cases. Once you've established that your repository.save() behaves correctly (and that any incorrect behavior will be caught as a test failure), then invocations of repository.save() don't need to be tested for their detailed correct behavior elsewhere in your application—you've already checked this through narrow and specific tests. You may still invoke repository.save() at higher levels, like broad system tests and end-to-end tests, but at that point you're testing the integration between those tested pieces rather than retesting the pieces themselves. You might still verify that the method was called, either by direct inspection or via its expected side effects, but at that point your verifications don't need to be very detailed because you've abstracted the behavior into well-tested components.

As noted in the comments, if the behavior of repository.save() comes entirely from Spring, then you probably don't need to test it heavily—the upstream tests within the Spring codebase should protect you there, just as your unit tests would protect your integration tests. Test the parts of the code that you write, and especially test the risky behaviors that aren't otherwise covered by narrower tests. Conversely, if you wanted to check that calls to repository.save() invoke expected validations or post-save behaviors, that might be an important thing to test for your repostiory implementation.

Because this question is less about your specific code and more about the practices of unit testing, you might also consult the Software Engineering Stack Exchange. I've written a related answer there.

Not the answer you're looking for? Browse other questions tagged or ask your own question.