【问题标题】:How to forward the local port of a SpringBootTest to a test configuration如何将 SpringBootTest 的本地端口转发到测试配置
【发布时间】:2019-01-08 18:09:42
【问题描述】:

我目前正在为 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 类中的服务器端口评估工作正常。

有解决这个问题的想法吗?

谢谢

【问题讨论】:

    标签: kotlin spring-boot-test spring-boot-configuration


    【解决方案1】:

    这是我们在这种情况下所做的:

    @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
        }
    }
    

    【讨论】:

    • lateinit 不适用于原始类型。我不明白这是如何标记为解决方案的。
    • 使用 java.lang.Integer 代替 Int
    【解决方案2】:

    使用 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")
        }
    }
    

    【讨论】:

      【解决方案3】:

      对我来说非常适合的大于 2.0.0 的 spring 版本的解决方案是:

      @Configuration
      open class TestTemplateConfig {
          private var localPort: Int? = null
      
          @EventListener(WebServerInitializedEvent::class)
          fun onServletContainerInitialized(event: WebServerInitializedEvent) {
              localPort = event.webServer.port
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2019-07-15
        • 1970-01-01
        • 2014-08-30
        • 2013-10-18
        • 2017-04-27
        • 2020-01-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多