Skip to content

random port not working for TestNG tests #2135

@wimdeblauwe

Description

@wimdeblauwe

Use Spring Boot 1.2.0, selecting a random port for integration tests does not work for TestNG based tests. I have converted the SpringApplicationIntegrationTestTests.java from JUnit to TestNG. This test fails:

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory;
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
import org.springframework.boot.test.IntegrationTest;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.test.context.testng.AbstractTestNGSpringContextTests;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.testng.annotations.Test;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;

@SpringApplicationConfiguration(classes = SpringApplicationIntegrationTestTestsWithTestNG.Config.class)
@WebAppConfiguration
@IntegrationTest({"server.port=0", "value=123"})
public class SpringApplicationIntegrationTestTestsWithTestNG extends AbstractTestNGSpringContextTests
{

    @Value("${local.server.port}")
    private int port = 0;

    @Value("${value}")
    private int value = 0;

    @Test
    public void runAndTestHttpEndpoint()
    {
        assertNotEquals( 8080, this.port );
        assertNotEquals( 0, this.port );
        String body = new RestTemplate().getForObject( "http://localhost:" + this.port
                                                               + "/", String.class );
        assertEquals( "Hello World", body );
    }

    @Test
    public void annotationAttributesOverridePropertiesFile() throws Exception
    {
        assertEquals( 123, this.value );
    }

    @Configuration
    @EnableWebMvc
    @RestController
    protected static class Config
    {

        @Value("${server.port:8080}")
        private int port = 8080;

        @Bean
        public DispatcherServlet dispatcherServlet()
        {
            return new DispatcherServlet();
        }

        @Bean
        public EmbeddedServletContainerFactory embeddedServletContainer()
        {
            TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory();
            factory.setPort( this.port );
            return factory;
        }

        @Bean
        public static PropertySourcesPlaceholderConfigurer propertyPlaceholder()
        {
            return new PropertySourcesPlaceholderConfigurer();
        }

        @RequestMapping("/")
        public String home()
        {
            return "Hello World";
        }

    }
}

The only way to fix it is to explicitly add the IntegrationTestPropertiesListener

@TestExecutionListeners(inheritListeners = false,
        listeners = {
                    IntegrationTestPropertiesListener.class,
                DependencyInjectionTestExecutionListener.class,
                DirtiesContextTestExecutionListener.class
        })

The problem is that the class is package protected, so I cannot reference it. I have tested it with copying the code of the listener and referencing that, and then the unit test is ok.

AbstractTestNGSpringContextTests has the following @TestExecutionListeners:

@TestExecutionListeners({ServletTestExecutionListener.class, DependencyInjectionTestExecutionListener.class, DirtiesContextTestExecutionListener.class})

So, or this has to change, or somehow these listeners defined in AbstractTestNGSpringContextTests have to be merged with those of @IntegrationTest or at the very least IntegrationTestPropertiesListener should be made public. In that last case, you might want to add a warning in the docs for TestNG users.

Metadata

Metadata

Assignees

No one assigned

    Labels

    type: regressionA regression from a previous release

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions