Как перенаправить локальный порт SpringBootTest в тестовую конфигурацию

В настоящее время я борюсь с внедрением порта сервера экземпляра SpringBootTest. Я написал тестовый класс конфигурации, где я хотел бы получить доступ к этому порту.

Класс конфигурации теста:

@Target(AnnotationTarget.CLASS, AnnotationTarget.FILE)
@Retention(AnnotationRetention.RUNTIME)
@Import(value = [TestTemplateConfig::class])
annotation class TestAnnotation

@Configuration
open class TestTemplateConfig {
    @Value("\${server.port}")
    private var localPort: Int? = null

    @Bean
    open fun foo() = Foo(localPort)
}

Тест выглядит так:

@SpringBootJunit5Test
@TestAnnotation
@EnableTestCouchbase
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class MyIntegrationTest {
    @LocalServerPort
    var port: Int = 0

    @Autowired
    private lateinit var foo: Foo

    ...
}

Теперь проблема в том, что я всегда получаю нулевое значение для порта в классе конфигурации. Поскольку я не получаю null, это звучит так, как будто он работает, чтобы получить порт, но неправильный (я думаю, что ноль определен для случайного порта весной). Оценка порта сервера в классе MyIntegrationTest пока работает правильно.

Любые идеи, чтобы исправить это?

Спасибо


person Stefan S.    schedule 01.08.2018    source источник


Ответы (3)


Вот что мы сделали в этом случае:

@Configuration
class Config {
    private lateinit var port: java.lang.Integer // declare a var to store the port
    
    @EventListener // subscribe to servlet container initialized event
    fun onServletContainerInitialized(event: EmbeddedServletContainerInitializedEvent) {
        port = event.embeddedServletContainer.port // when event is fired, extract the port for that event
    }
}
person SimY4    schedule 01.08.2018
comment
lateinit не работает для примитивных типов. Я не понимаю, как это помечено как решение. - person Czar; 23.07.2019
comment
Используйте java.lang.Integer вместо Int - person SimY4; 08.07.2020

С Spring Boot 2.1.6 это работает для меня:

import com.example.MyApplication
import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment
import org.springframework.boot.web.server.LocalServerPort
import org.springframework.context.support.GenericApplicationContext
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig

@SpringJUnitConfig
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, classes = [MyApplication::class])
class ApplicationStartsTest {
    @LocalServerPort
    protected var port: Int = 0

    @Autowired
    lateinit var context: GenericApplicationContext

    @Test
    fun `application context is initialized`() {
        assertTrue(::context.isInitialized, "Application context should have been injected")
    }

    @Test
    fun `web application port is assigned`() {
        assertTrue(port != 0, "web application port should have been injected")
    }
}
person Czar    schedule 23.07.2019

Решение для весенней версии выше 2.0.0, которое отлично работает для меня, таково:

@Configuration
open class TestTemplateConfig {
    private var localPort: Int? = null

    @EventListener(WebServerInitializedEvent::class)
    fun onServletContainerInitialized(event: WebServerInitializedEvent) {
        localPort = event.webServer.port
    }
}
person Stefan S.    schedule 01.08.2018