Spring boot:@ConfigurationProperties 对测试不满意 [英] Spring boot: @ConfigurationProperties not satisfied on test
问题描述
我在测试执行中遇到此异常:
I'm getting this exception on my test excution:
UnsatisfiedDependencyException:创建名为net.gencat.transversal.espaidoc.mongo.GridFSTest"的bean时出错:通过字段resourceProperties"表达的不满意依赖;嵌套异常是 org.springframework.beans.factory.NoSuchBeanDefinitionException:没有可用的net.gencat.transversal.espaidoc.ResourcesConfigProperties"类型的合格 bean:预计至少有 1 个 bean 有资格作为自动装配候选.
UnsatisfiedDependencyException: Error creating bean with name 'net.gencat.transversal.espaidoc.mongo.GridFSTest': Unsatisfied dependency expressed through field 'resourceProperties'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'net.gencat.transversal.espaidoc.ResourcesConfigProperties' available: expected at least 1 bean which qualifies as autowire candidate.
所以,我认为消息已经足够清楚了:ResourcesConfigProperties 不满意
.
So, I think message is so clear enough: ResourcesConfigProperties is not satisfied
.
我的测试:
RunWith(SpringRunner.class)
@SpringBootTest()
public class GridFSTest {
@Autowired
private GridFsTemplate gridFsTemplate;
@Autowired
private ResourcesConfigProperties resourceProperties;
public URL getHugeResource() {
try {
return Paths
.get(this.resourceProperties.getHuge())
.toUri()
.toURL();
} catch (MalformedURLException e) {
return null;
}
}
@Test
public void storeHugeFile() throws IOException {
URL resource = this.getHugeResource();
this.gridFsTemplate.store(
resource.openStream(),
resource.getPath(),
"mime"
);
}
}
和 ResourcesConfigProperties
是:
@ConfigurationProperties(prefix = "files")
public class ResourcesConfigProperties {
private String huge;
/**
* @return the huge
*/
public String getHuge() {
return huge;
}
/**
* @param huge the huge to set
*/
public void setHuge(String huge) {
this.huge = huge;
}
}
进入我的 src/test/resources
我有我的 application.properties
文件:
into my src/test/resources
I have my application.properties
file:
files.huge: /home/jcabre/Downloads/1GB.zip
有什么想法吗?
编辑
主 Spring 启动应用程序:
Main Spring boot application:
@SpringBootApplication(
//scanBasePackages = { "cat.gencat.ctti.canigo.arch.web.rs" },
exclude = JmxAutoConfiguration.class
)
@EnableConfigurationProperties({
ApiProperties.class,
FileStoreProperties.class
})
@Import(RedisConfiguration.class)
public class ApiApplication {
public static void main(String[] args) {
SpringApplication.run(ApiApplication.class, args);
}
}
推荐答案
TL;DR:
它正在发生,因为 @ConfigurationProperties
不是由应用程序上下文管理的您在测试中构建,尽管它们会在应用程序启动时加载,因为您有@EnableConfigurationProperties
在您的应用主类上.
TL;DR:
It is happening, because the @ConfigurationProperties
are not managed by the application context you build in tests, although they will be load when the application launches, because you have @EnableConfigurationProperties
on your app main class.
@EnableConfigurationProperties
仅影响您在 bootRun
时拥有的应用程序上下文,但不会影响 @SpringBootTest
.在许多情况下,您在测试中构建的应用程序上下文可能与 bootRun
的应用程序上下文不同,就像您的情况一样.
@EnableConfigurationProperties
on main class only affect the application context you have when you bootRun
, but not that in a @SpringBootTest
. The application context you build in tests could be, under many circumstances, distinct with that of bootRun
, just like in your case.
您可以在 gradle bootRun
和 gradle test
中添加 @Component
以使上下文知道它.这是最简单的方法,但不是 100% 建议的方法.
You can add @Component
to make the context be aware of it, both in gradle bootRun
and in gradle test
. It's the easiest way, but not 100% the suggested way.
相反,您可以在 @SpringBootTest
中添加 @EnableConfigurationProperties({Config1.class, Config2.class})
,只将部分配置属性类注入到上下文,以避免注入开销.
Instead, you can add @EnableConfigurationProperties({Config1.class, Config2.class})
in a @SpringBootTest
, to inject only some of the configuration properties class into the context, to avoid injection overhead.
它会是这样的:
//@RunWith(SpringRunner.class) // for JUnit4 in Spring
@ExtendWith(SpringExtension.class) // for JUnit5 in Spring.
@SpringBootTest
@EnableConfigurationProperties({
ResourcesConfigProperties.class,
})
@Data
public class ConfigsTest {
@Autowired
private ResourcesConfigProperties resourceConfigProperties;
...
}
<小时>
更好的是,您可以使用 @SpringBootTest(classes={})
:{}
中的类是您想要 @SpringBootTest<的应用程序上下文的类/code> 来管理(创建、初始化、从 yaml 文件加载属性等).这样你就不必加载所有的上下文,而只需加载其中的一部分.
Better yet, you can use @SpringBootTest(classes={})
: classes within {}
are those you want the application context of @SpringBootTest
to manage(creation, initialization, loading properties from yaml files, and so on). Then you don't have to load all the context, but only part of it.
您可以将@ConfigurationProperties
的所有类归为一类@Configuration
,并放入classes={}
code>@SpringBootTest,而不是到处重复这个 @ConfigurationProperties
列表.类似的东西:
You can group all classes of @ConfigurationProperties
in one class of @Configuration
, and put it in the classes={}
of @SpringBootTest
, instead of repeating this list of @ConfigurationProperties
everywhere. Something like:
//@RunWith(SpringRunner.class) // for JUnit4 in Spring
@ExtendWith(SpringExtension.class) // for JUnit5 in Spring.
@SpringBootTest(classes = {
TestConfiguration.class
})
@Data
public class ConfigsTest {
@Autowired
private ResourcesConfigProperties resourceConfigProperties;
...
}
TestConfiguration.java
:
@EnableConfigurationProperties({
ResourcesConfigProperties.class,
})
@Configuration
public class TestConfiguration {
}
这篇关于Spring boot:@ConfigurationProperties 对测试不满意的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!