Search code examples
javaspring-bootintegration-testingspring-boot-testspringmockito

What is the best way to test Spring Boot application? With server involvement or by creating mock environment?


I want to test my Spring Boot application's layers - service, data, controllers.

I know with Spring Boot we can test these with server involvement or without involvement (by creating a mock environment). So my question here is - what is the best practise to test these layers? Or if it depends on the specific layer which we want to test?


Solution

  • Unit testing is straightforward.. you stick to SRP principle, mock out all the collaborators and test in isolation.

    When it comes to integration testing there is no clear answer and definite standard. It always depends on the project you are working on and even the specific feature.

    After working with a few Spring Boot applications I am leaning towards splitting your IT suite into four parts/categories:

    1) REST API Tests

    So we test only the @Restontrollers. You use @WebMvcTest(MyController.class) or @WebFluxTest(MyController.class) depending on why type of controller you use. Anything from the service layer down is mocked. You put as much emphasis on inputs params/request body as possible and test the hell out of every combination.

    2) Repository Tests

    Tests that verify the ORM layer only. You use @DataJpaTest for this. Here you test every possible scenario for each repository method you have, without caring what invoked it etc.

    3) Slice Tests

    This is where you verify the interaction between your @Component and @Service beans. This is where the actual business logic of your app is tested. It is up to decide whether you send the data via REST or use a call to the top-most @Service. I always stubbed the @Repository layer though in this case.

    4) End to End Tests

    These work on a real Web Server:

    @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)

    Nothing is mocked here.

    Discussion

    The key here is to decide how much each of these should be used, keeping in mind that slice testing is probably the most important.

    The main emphasis should NOT be put on E2E tests for sure. They are sort of a comma at the end of a sentence. They are the slowest and require most set-up. Thus they are most error-prone, hard to maintain and hard to understand. Ideally, these should be kept to a bare minimum (most crucial cases covered only).

    Also when running your IT suite they should be grouped in this order:

    1) Controller Tests

    2) Slice Tests

    3) Repository Tests

    4) E2E Tests

    (from the fastest and requiring least environment interaction to the slowest).

    Again, it is up to the team to decide which ones of these we want to use, in what order and with what frequency.

    Additional Read: I have written an article about common integration testing mistakes which may complement information given above and help you out even further in your projects.