春季启动:测试未满足@ConfigurationProperties

时间:2018-10-02 09:24:30

标签: spring-boot spring-boot-test

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

  

UnsatisfiedDependencyException:创建名称为'net.gencat.transversal.espaidoc.mongo.GridFSTest'的bean时出错:通过字段'resourceProperties'表示的不满足的依赖关系;嵌套的异常是org.springframework.beans.factory.NoSuchBeanDefinitionException:没有类型为'net.gencat.transversal.espaidoc.ResourcesConfigProperties'的合格bean:期望至少有1个有资格作为自动装配候选的bean。

所以,我认为消息非常清晰: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文件:

files.huge: /home/jcabre/Downloads/1GB.zip

有什么想法吗?

编辑

主要的Spring引导应用程序:

@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);
    }
}

3 个答案:

答案 0 :(得分:1)

TL; DR:

之所以会这样,是因为@ConfigurationProperties不受您在测试中构建的应用程序上下文的管理,尽管它们将在应用程序启动时加载,因为您拥有{{1} }在您的应用主类上。

主类上的

@EnableConfigurationProperties仅影响@EnableConfigurationProperties时的应用上下文,而不会影响bootRun 中的应用上下文。在很多情况下,就像在您的情况下一样,您在测试中构建的应用程序上下文可能与@SpringBootTest有所不同。

您可以在bootRun@Component中添加gradle bootRun以使上下文知道它。这是最简单的方法,但不是建议的方法的100%。


如果有时间,可以使用更正确的方式获取详细信息

相反,您可以在gradle test中添加@EnableConfigurationProperties({Config1.class, Config2.class}),以便仅将一些配置属性类注入到上下文中,以避免注入开销。

那将是:

@SpringBootTest

更好的是,您可以使用//@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={})中的类是您希望{}的应用程序上下文进行管理的类(创建,初始化,从Yaml文件加载属性等等。上)。然后,您不必加载所有上下文,而只需加载其中的一部分。

您可以将@SpringBootTest的所有类别归为一类@ConfigurationProperties,然后将其放入@Configuration的{​​{1}}中,而不必重复此{{1 }}无处不在。像这样:

classes={}

@SpringBootTest

@ConfigurationProperties

答案 1 :(得分:0)

您需要在主Spring Boot类的ResourcesConfigProperties注释中添加EnableConfigurationProperties,这将为您加载并从ResourceConfigProperties中创建一个bean

如果您不想将@Component添加到ResourceConfigProperties注释中,也可以将EnableConfigurationProperties添加到SpringBootTest中。

在使用SpringBootApplication或任何切片测试时,它将使用注解的内容或在测试上下文中的主{{1}}中定义的bean。

答案 2 :(得分:-1)

您还需要使用ResourcesConfigProperties注释@Configuration类,如下所示,否则它将不会在spring容器中创建此类的bean。

@Configuration
@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;
    }

}