Most modern applications use databases or some kind of third-party services and we, as developers, are often in situations where we need to integrate with them. Tests that evaluate interactions between different parts of the system are called Integration tests. The idea behind integration tests is to verify that different components of our system are working properly together.
In the Spring environment, we have various tools that can help us write integration tests. In this article, we will see code examples that use JUnit, Mockito and MockWebServer.
Proper communication with the database is essential and we want to make sure that our database operations are performed correctly. If we were to test any operation while using it, would that mean we are changing data in the database? We don't want inconsistent data because of tests!
There are few ways how to approach this:
First, we will configure our H2 database in the configuration files by creating application-embedded.yml file inside the test/resources package. Our configuration says that the H2 database will be created when we run our tests. To have the desired database schema, we use Liquibase migration in this example.
Let's create tests for some basic CRUD operations.
Our persistent database is PostgreSQL and for testing we are using an H2 in-memory database which will have a lifespan of our test execution time. That means we can run tests repeatedly, without worrying about changing data in our persistent database, all tests are executing operations on H2.
Let's now take a look at another approach to testing the persistence layer. When testing with containers, such as Docker, we can spin up a copy of anything inside the container. In this example, we'll take a look at how to start a PostgreSQL database in a container and use it to test our persistence layer. To achieve that, we'll use the Testcontainers framework.
We can first start by defining the base class, which will be responsible for managing our container:
The next step is simply to extend this class and create our tests, we'll test the same methods as in the previous example:
This approach is really powerful, but we have to keep in mind that Docker should be installed and running on our machine before running tests.
Testing the presentation layer means that we want to validate our API endpoints and controllers. With Spring's MockMvc we can simulate performing HTTP requests and verifying responses. As stated in official documentation, we are able to test endpoints the same way as if they were processing real HTTP requests, but without the cost of starting the server.
Let's see an example, this is our controller with two very simple endpoints:
We can now proceed to testing with MockMvc.
Interactions with external APIs are usually really important to our application, so we want to be sure that integration between them is working properly. One approach for this kind of testing is to use MockWebServer, which allows us to mock HTTP responses from external servers. With MockWebServer we can simulate different scenarios, such as successful response, error response, timeouts, etc.
MockWebServer is part of OkHttp library, so we need to include its dependency in our build tool. Before executing tests, we should start the mock server and to do that, we could use the JUnit @BeforeAll annotation. Similarly, after testing is complete, we can use the @AfterAll annotation to shut down the server.
We have managed to set up MockWebServer, the next step is to enqueue our desired response and write a test that is going to verify it.
In this article, we saw how to test persistence and presentation layers as well as communication with external services. Testing is a critical part of a successful SDLC process. If different layers of application are properly tested, we can build confidence in the quality of our product and deliver more stable versions of it.
Full source code available over on GitLab.
https://testcontainers.com/modules/postgresql/
https://spring.io/guides/gs/testing-web
https://github.com/square/okhttp/blob/master/mockwebserver/README.md
https://gitlab.serengetitech.com/aleksandar.pelanovic/integrationtest