Spring Boot Test failing to autowire port with LocalServerPort annotation
Asked Answered
J

7

6

I am running Spring Boot 2.0.1 and Junit 5. I am trying to get port within an integration test . However the port value is always zero. I am not sure what could be causing it. I have tried changing web environment enum to random port but nothing seems to be working.

package com.example.demo;

import org.junit.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import static org.junit.jupiter.api.Assertions.assertNotEquals;

@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
public class DemoApplicationTests {

@LocalServerPort
private int port;
@Test


public void printPort() throws Exception {
     assertNotEquals(port, 0);
}
}

The following is the pom (NB. only shows the dependencies)

<properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <junit-jupiter.version>5.2.0</junit-jupiter.version>
        <junit-platform.version>1.2.0</junit-platform.version>
    </properties>

    <dependencies>
         <dependency>
                <groupId>org.junit.platform</groupId>
                <artifactId>junit-platform-launcher</artifactId>
                <scope>test</scope>
                <version>${junit-platform.version}</version>
            </dependency>
            <dependency>
                <groupId>org.junit.platform</groupId>
                <artifactId>junit-platform-engine</artifactId>
                <scope>test</scope>
                <version>${junit-platform.version}</version>
            </dependency>
            <dependency>
                <groupId>org.junit.jupiter</groupId>
                <artifactId>junit-jupiter-api</artifactId>
                <scope>test</scope>
                <version>${junit-jupiter.version}</version>
            </dependency>
            <dependency>
                <groupId>org.junit.jupiter</groupId>
                <artifactId>junit-jupiter-engine</artifactId>
                <scope>test</scope>
                <version>${junit-jupiter.version}</version>
            </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

application.properties

server.port=8080
Jabez answered 8/5, 2018 at 17:38 Comment(1)
Relaterd: #30312558Comprehension
H
9

I had the same problem, this set of annotations below worked for me. Without @ContextConfiguration port was 0.

@ContextConfiguration
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class TestBase {

@LocalServerPort
protected int port;

}
Herndon answered 26/11, 2018 at 9:29 Comment(2)
There is no @RunWith in JUnit5Scruggs
Use @ExtendWith in JUnit5Tinder
S
4

I had same problem. This solution worked for me:

@Service
public class TestService implements ApplicationListener<ServletWebServerInitializedEvent> {

   private int localPort;

   @Override
   public void onApplicationEvent(final ServletWebServerInitializedEvent event) {
       localPort = event.getWebServer().getPort();
   }
}

You can autowire this service or you can implement ApplicationListener directly in your test class. Just a warning - the localPort variable is initialized during application startup after the bean is completely ready, so it won't be available in @PostConstruct etc.

Saharan answered 29/10, 2018 at 17:47 Comment(0)
G
2

You're missing a dependency on spring-boot-starter-web.

Gardant answered 9/5, 2018 at 10:44 Comment(0)
Z
1

I have the same problem, and i am using junit5, i guess your problem should be the same. just do as below:

  • remove the "import org.junit.Test";
  • reimport the "import org.junit.jupiter.api.Test";

this should solve the problem

Zingale answered 29/9, 2020 at 8:34 Comment(0)
M
1

I had this problem, After debugging I find out that the port initialization take time. So I changed my test case like this:

@LocalServerPort
lateinit var port: Number

val baseUrl by lazy {  "http://localhost:$port"}
Mussel answered 1/1, 2022 at 8:21 Comment(0)
P
0

Add @TestPropertySource(locations = "classpath:test.properties") on top of your test class. Have you tried @Value("${server.port}") instead of @LocalServerPort?

Paulsen answered 8/5, 2018 at 18:6 Comment(0)
C
0

Here you can find an example using RANDOM_PORT. You can change to DEFINED_PORT simply changing the value of webEnvironment and in that case the value of the variable serverPort will be 8080, the default one.

Cranmer answered 9/5, 2018 at 9:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.