Running Integration Tests with Spring Boot

A common issue, if you want to run Integration Tests in Spring Boot application in the same phase when you build your application is that you won’t be able to connect the Test to the application:

$ mvn install spring-boot:run  [ERROR] Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 3.434 s <<< FAILURE! - in com.example.testrest.DemoApplicationTests [ERROR] testCustomerList(com.example.testrest.DemoApplicationTests)  Time elapsed: 1.004 s  <<< ERROR! java.net.ConnectException: Connection refused (Connection refused)

This is due to the fact, that the port chosen during the Test Phase is random, therefore most of the time you will get a Connection refused Exception.

How to fix it

In older versions of Spring Boot, you could add the annotation @IntegrationTest to your application to solve the issue, however that has been deprecated and removed in Spring Boot 2. The simplest way to get around the problem is to specify the SpringBootTest.WebEnvironment.DEFINED_PORT in your @SpringBootTest Class as follows:

package com.example.testrest;

import org.hamcrest.Matchers;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import static io.restassured.RestAssured.get;
import static org.hamcrest.CoreMatchers.is;

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
public class DemoApplicationTests {
  @Test
  public void testCustomerList() {
    get("http://localhost:8080/list").then().assertThat().statusCode(200).body("size()", is(5));
    get("http://localhost:8080/one/0")
        .then()
        .assertThat()
        .statusCode(200)
        .body("name", Matchers.equalTo("Fred"));
    get("http://localhost:8080/one/1")
        .then()
        .assertThat()
        .statusCode(200)
        .body("name", Matchers.equalTo("Barney"));
  }
}