簡體   English   中英

SpringBoot 單元測試未正確獲取 @Component 自動裝配 object 的 @Value

[英]SpringBoot unit test not getting @Value correctely of a @Component autowired object

我正在實現一個非常示例的單元測試,它增加了谷歌番石榴庫 CacheLoader 的計數器並獲取值。

速率限制測試

@RunWith(SpringRunner.class)
@ContextConfiguration(classes = RateLimitTestConfiguration.class)
public class RateLimitTest {

    @Autowired
    RateLimitFilter rateLimitFilter;

    @Test
    public void incrementCounter_whenGetCounter_existsKey_and_returnIncrementedValue() throws ExecutionException {
        final int times = 10;
        final String counterName = "TestCounter";
        int i = 0;
        for(i = 0; i < 10; i++)  {
            rateLimitFilter.getRequestCountPerApiKey().put(counterName,i);
        }
        Assert.assertNotNull(rateLimitFilter.getRequestCountPerApiKey().get(counterName));
        Assert.assertEquals(Long.valueOf(times),Long.valueOf(rateLimitFilter.getRequestCountPerApiKey().get(counterName)));
    }

}

所以我在測試上下文中實現了一個@Bean:

@Configuration
public class RateLimitTestConfiguration {

    @Bean
    public RateLimitFilter rateLimitFilter() {
        return new RateLimitFilter();
    }

}

這是應用正常的class:

@Component
public class RateLimitFilter implements GatewayFilter {

    final Logger LOGGER = LoggerFactory.getLogger(RateLimitFilter.class);

    @Value("${throttling.request.rate.minute}")
    private int MAX_REQUEST_PER_MINUTE;

    private LoadingCache<String,Integer> requestCountPerApiKey;

    ....

public LoadingCache<String, Integer> getRequestCountPerApiKey() {
        return requestCountPerApiKey;
    }
}

在我設置的測試的application.yml上:

throttling:
  request:
    rate:
      minute: 5

並且測試失敗並出現錯誤:

 Caused by: org.springframework.beans.TypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'int'; nested exception is java.lang.NumberFormatException: For input string: "${throttling.request.rate.minute}"
        at org.springframework.beans.TypeConverterSupport.convertIfNecessary(TypeConverterSupport.java:79)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1252)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1224)
        at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:640)
        ... 55 common frames omitted
    Caused by: java.lang.NumberFormatException: For input string: "${throttling.request.rate.minute}"
        at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
        at java.base/java.lang.Integer.parseInt(Integer.java:638)
        at java.base/java.lang.Integer.valueOf(Integer.java:983)
        at org.springframework.util.NumberUtils.parseNumber(NumberUtils.java:211)
        at org.springframework.beans.propertyeditors.CustomNumberEditor.setAsText(CustomNumberEditor.java:115)
        at org.springframework.beans.TypeConverterDelegate.doConvertTextValue(TypeConverterDelegate.java:429)
        at org.springframework.beans.TypeConverterDelegate.doConvertValue(TypeConverterDelegate.java:402)
        at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:155)
        at org.springframework.beans.TypeConverterSupport.convertIfNecessary(TypeConverterSupport.java:73)

有很多方法可以讓它發揮作用。 我會給其中兩個:

  1. 您可以簡單地將@ContextConfiguration(classes = RateLimitTestConfiguration.class)替換為@SpringBootTest(classes = RateLimitTestConfiguration.class) 僅適用於 Spring 引導。
  2. 您可以手動將PropertySourcesPlaceholderConfigurer bean 添加到您的配置中(第一種方法自動配置此 bean):
@Bean
public PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
    PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer();
    YamlPropertiesFactoryBean yaml = new YamlPropertiesFactoryBean();
    yaml.setResources(new ClassPathResource("application.yml"));
    propertySourcesPlaceholderConfigurer.setProperties(yaml.getObject());
    return propertySourcesPlaceholderConfigurer;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM