gpt4 book ai didi

java - Spring Boot 测试用例不使用自定义转换服务

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:53:26 25 4
gpt4 key购买 nike

我正在尝试使用 Spring Boot Test 编写集成测试用例。

我自定义 ConversionService 以了解新的 java.time 类型:

@Configuration
public class ConversionServiceConfiguration {
@Bean
public static ConversionService conversionService() {
final FormattingConversionService reg = new DefaultFormattingConversionService();
new DateTimeFormatterRegistrar().registerFormatters(reg);
return reg;
}
}

然后期望它能工作:

@Component
class MyServiceConfig {
@Value("${max-watch-time:PT20s}")
private Duration maxWatchTime = Duration.ofSeconds(20);
}

在正常的 SpringApplication.run 下运行时,这似乎工作正常。但是,在我的测试用例中:

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT, classes= {
MyServiceMain.class,
AttachClientRule.class
})
public class MyTest {
@Inject
@Rule
public AttachClientRule client;

@Test(expected=IllegalArgumentException.class)
public void testBad() throws Exception {
client.doSomethingIllegal();
}
}

它爆炸了:

Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'AttachClientRule': Unsatisfied dependency expressed through constructor parameter 0:

Error creating bean with name 'MyServiceConfig': Unsatisfied dependency expressed through field 'maxWatchTime': 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;

深入了解执行实际转换的 TypeConverterDelegate 的内部结构,它似乎捕获了从 DefaultListableBeanFactory 上的字段使用的 ConversionService >。在设置该字段的位置设置一个观察点,我找到了 AbstractApplicationContext.refresh() 方法:

// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh(); // <--- MyServiceConfig initialized here
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory); // <--- DefaultListableBeanFactory.conversionService set here!!!
// Last step: publish corresponding event.
finishRefresh();

因此 @Value 注入(inject)发生在 ConversionService 应用于 BeanFactory 之前。没有布埃诺!

我发现了一个似乎是解决方法的方法:

@Configuration
public class ConversionServiceConfiguration implements BeanFactoryPostProcessor {
@Bean
public static ConversionService conversionService() {
final FormattingConversionService reg = new DefaultFormattingConversionService();
new DateTimeFormatterRegistrar().registerFormatters(reg);
return reg;
}

@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
beanFactory.setConversionService(conversionService());
}
}

这会强制初始化更早发生,但感觉不是正确的解决方案(至少没有这样记录)。

我哪里做错了?Spring 4.3.0、Spring Boot 1.4.0M3

编辑

现在我发现了另一种让它失败的方法!不使相同的配置类实现 EnvironmentAware:

@Override
public void setEnvironment(Environment environment) {
((AbstractEnvironment) environment).setConversionService(conversionService());
}

我发现 PropertySourcesPropertyResolver 使用了错误的(默认)ConversionService。这让我发疯!

Caused by: java.lang.IllegalArgumentException: Cannot convert value [PT15s] from source type [String] to target type [Duration] at org.springframework.core.env.PropertySourcesPropertyResolver.getProperty(PropertySourcesPropertyResolver.java:94) at org.springframework.core.env.PropertySourcesPropertyResolver.getProperty(PropertySourcesPropertyResolver.java:65) at org.springframework.core.env.AbstractPropertyResolver.getProperty(AbstractPropertyResolver.java:143) at org.springframework.core.env.AbstractEnvironment.getProperty(AbstractEnvironment.java:546) at com.mycorp.DoSomething.go(DoSomething.java:103)

最佳答案

Spring Boot 开发人员已确认这没有很好的文档记录并且无法按规定工作:https://github.com/spring-projects/spring-boot/issues/6222

关于java - Spring Boot 测试用例不使用自定义转换服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37952166/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com