Spring boot:@ConfigurationProperties 对测试不满意 [英] Spring boot: @ConfigurationProperties not satisfied on test

查看:40
本文介绍了Spring boot:@ConfigurationProperties 对测试不满意的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在测试执行中遇到此异常:

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 bootRungradle 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆