Skip to content

Latest commit

 

History

History
74 lines (54 loc) · 3.91 KB

README.md

File metadata and controls

74 lines (54 loc) · 3.91 KB

Example of Component Testing in Java

This is an example project showcasing how a microservice can be tested in Java.

Motivation

A microservice has dependencies to databases and external services. When a microservice is changed, it is important to know if the functionality provided to the end user still works as expected. One way to achieve that is end-to-end testing. This testing method spawns the whole application stack and tests the system as a whole.

It has several disadvantages.

  • The startup of the application stack is slow and resource intensive, making it infeasible to run the tests for small changes.
  • Failed tests can not necessarily be assigned to an individual service, causing a lack of responsibility for failed tests.
  • It might not be possible to spawn all required dependencies.

Component testing aims to not have this disadvantages. This testing method only focuses on a single microservice, eliminating the need to spawn the whole application stack. Instead, only direct dependencies are spawned. These direct dependencies can be either mocked (often the case for external services) or unmocked (often the case for databases).

As a consequence, it becomes feasible to run the tests for single changes on developer machines and on a CI server. This increases developer's confidence in their changes allowing them to deploy changes earlier, in smaller chunks and more frequently.

Application

The application under test offers an HTTP API to execute runs creating items in an external service. It uses a PostgreSQL database for the persistence of runs.

The application uses several libraries to simplify the implementation.

  • The framework Dropwizard with Jersey to expose endpoints
  • The library liquibase for the database schema creation
  • The library JDBI to execute queries against the database
  • The library retrofit to execute requests against the external service

Test Strategy

The tests focus on three different parts of the application.

  1. The schema creation of the database and the application's interface to the database
  2. The business logic calling the external service
  3. The logic of the endpoints and how they affect each other

Database Tests

The first aspect is tested in the RunDAOTest. This test utilizes testcontainers to spawn a docker container with a PostgreSQL database. It runs the liquibase schema migration of the application on the spawned database and tests the defined queries of the application's DAO.

Business Logic and External Service Tests

The second aspect is tested in the RunServiceTest. This test utilizes testcontainers to spawn a docker container with a mock server. It executes the business logic of the application and verifies that the application sends the expected requests to the mock of the external service.

Resource Tests

The third aspect is tested in the RunResourceTest. This test utilizes testcontainers to spawn a docker container with a PostgreSQL database. In contrast to the database tests, it uses a globally spawned docker container instead of a dedicated one. It uses Mockito to mock the business logic of the application. It calls the endpoints and verifies that they return the expected responses.

Setup, Build and Run

Make sure you have docker, docker-compose, Maven 3.6.x and Java 11 installed. Ensure that the docker daemon is running.

  1. Run mvn clean package
  2. Run docker-compose up -d to start the PostgreSQL database and a mock server.
  3. Start the Java application from an IDE or command line.
  4. Run curl -X POST localhost:4201/runs?item_count=3 to create a run.
  5. Run curl localhost:4201/runs to retrieve all runs.
  6. Run curl -X PUT "localhost:4203/mockserver/retrieve?type=REQUESTS" to inspect the calls being send to the mock server.
  7. Run docker-compose down to shutdown the database and the mock server.