【问题标题】:Spring @Value injection conversion not working in @SpringJUnitConfig testSpring @Value 注入转换在 @SpringJUnitConfig 测试中不起作用
【发布时间】:2021-03-31 17:03:32
【问题描述】:

在使用@SpringJUnitConfig 测试时,我找不到在注入@Value 时进行自动值转换的方法。

例如,对于给定的代码:

@SpringBootApplication
class DemoApplication

fun main(args: Array<String>) {
    runApplication<DemoApplication>(*args)
}

@Component
class ValueConvertInjection(@Value("2ms") val duration : java.time.Duration) {
    @PostConstruct
    fun init() = println("Duration converted: $duration")
}

给定的测试将失败:

@SpringJUnitConfig(classes = [ValueConvertInjection::class])
class JUnitValueConvertInjectionTest {
    @Autowired
    lateinit var vi :ValueConvertInjection

    @Test
    fun test() = assert(vi.duration == Duration.ofMillis(2))
    
}

以下例外:

...
Caused by: org.springframework.beans.ConversionNotSupportedException: Failed to convert value of type 'java.lang.String' to required type 'java.time.Duration'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type 'java.time.Duration': no matching editors or conversion strategy found
    at org.springframework.beans.TypeConverterSupport.convertIfNecessary(TypeConverterSupport.java:76)
    ... 85 more
Caused by: java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type 'java.time.Duration': no matching editors or conversion strategy found
    at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:262)
    at org.springframework.beans.TypeConverterSupport.convertIfNecessary(TypeConverterSupport.java:73)
    ... 89 more

我找不到应该添加到上下文中的内容,因此任何 Spring 转换都将被注册和选择。

【问题讨论】:

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


    【解决方案1】:

    要使用持续时间类,可以尝试如下

    @Component
    @ConfigurationProperties(prefix="time")
    class ValueConvertInjection {
     
        Duration val = Duration.ofSeconds(60);
    
        @PostConstruct
        fun init() = println("Duration converted: $duration")
    }
    
    

    在你的 src/test/resources 中,创建 application.yml

    time:
      val:
        2ms
    

    【讨论】:

    • 谢谢。那将是重构课程以解决问题——这并不是我所问的:我有兴趣看看如何解决测试对话问题。此外,在一些不太可能的合成用例中:即如果 bean 已经使用了另一个配置属性前缀,或者存在多个具有不同前缀的 @value 注释。
    【解决方案2】:

    Spring Boot 使用转换服务初始化上下文,这正是您所需要的:

    public class ConversionConfiguration {
        @Bean
        fun conversionService() = ApplicationConversionService.getSharedInstance()
    }
    
    @SpringJUnitConfig(classes = [
            ValueConvertInjection::class,
            ConversionConfguration::class
    ]) {
    class JUnitValueConvertInjectionTest {
        @Autowired
        lateinit var vi: ValueConvertInjection
    
        @Test
        fun test() = assert(vi.duration == Duration.ofMillis(2))   
    }
    

    【讨论】:

      猜你喜欢
      • 2017-10-10
      • 1970-01-01
      • 2013-03-20
      • 2018-03-03
      • 1970-01-01
      • 2021-06-30
      • 1970-01-01
      • 2018-01-24
      • 1970-01-01
      相关资源
      最近更新 更多