如何将 SpringBootTest 的本地端口转发到测试配置
How to forward the local port of a SpringBootTest to a test configuration
我目前正在为 SpringBootTest 实例的服务器端口注入而苦恼。我已经编写了一个测试配置 class,我想在其中访问此端口。
测试配置class:
@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
...
}
现在的问题是,我在配置 class 中收到的端口值始终为零。因为我没有得到空值,所以这听起来像是在努力获取端口,但是错误的端口(我认为零是为 spring 中的随机端口定义的)。 MyIntegrationTest class 中服务器端口的评估目前工作正常。
有解决此问题的想法吗?
谢谢
这是我们在这种情况下所做的:
@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
}
}
spring 版本大于 2.0.0 的解决方案对我来说是完美的,是:
@Configuration
open class TestTemplateConfig {
private var localPort: Int? = null
@EventListener(WebServerInitializedEvent::class)
fun onServletContainerInitialized(event: WebServerInitializedEvent) {
localPort = event.webServer.port
}
}
使用 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")
}
}
我目前正在为 SpringBootTest 实例的服务器端口注入而苦恼。我已经编写了一个测试配置 class,我想在其中访问此端口。
测试配置class:
@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
...
}
现在的问题是,我在配置 class 中收到的端口值始终为零。因为我没有得到空值,所以这听起来像是在努力获取端口,但是错误的端口(我认为零是为 spring 中的随机端口定义的)。 MyIntegrationTest class 中服务器端口的评估目前工作正常。
有解决此问题的想法吗?
谢谢
这是我们在这种情况下所做的:
@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
}
}
spring 版本大于 2.0.0 的解决方案对我来说是完美的,是:
@Configuration
open class TestTemplateConfig {
private var localPort: Int? = null
@EventListener(WebServerInitializedEvent::class)
fun onServletContainerInitialized(event: WebServerInitializedEvent) {
localPort = event.webServer.port
}
}
使用 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")
}
}