【问题标题】:Spring boot: @ConfigurationProperties not satisfied on test春季启动:@ConfigurationProperties 对测试不满意
【发布时间】:2019-03-07 10:00:05
【问题描述】:

我在执行测试时遇到了这个异常:

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

【问题讨论】:

  • 您的主 Spring 引导应用程序是什么样的?
  • 我刚刚编辑了帖子。
  • @Component 添加到ResourcesConfigProperties,因为@ConfigurationProperties 不导入任何创建bean 的spring 注释。
  • 你需要将@Configuration添加到ResourcesConfigProperties类,否则它不会在spring容器中创建这个类的bean,@Autowired将不起作用。

标签: spring-boot spring-boot-test


【解决方案1】:

TL;DR:

它正在发生,因为 @ConfigurationProperties 不是由应用程序上下文管理的主类。

主类上的@EnableConfigurationProperties 只会影响您在bootRun 时拥有的应用程序上下文,但不会影响@SpringBootTest 中的应用程序上下文。在许多情况下,您在测试中构建的应用程序上下文可能与 bootRun 不同,就像您的情况一样。

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


如果你有时间,更适当的方式与细节

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

应该是这样的:

//@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 的应用程序上下文管理的类(创建、初始化、从 yaml 文件加载属性等)。然后您不必加载所有上下文,而只需加载其中的一部分。

您可以将@ConfigurationProperties 的所有类分组到@Configuration 的一个类中,并将其放在@SpringBootTestclasses={} 中,而不是到处重复这个@ConfigurationProperties 列表。比如:

//@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 {
}

【讨论】:

  • 最后但同样重要的是,在映射类中添加@NoArgsConstructor@AllArgsConstructor;那又咬我了。而且,这些字段不能声明为final,也不能在该类上使用@Builder。它也不应该被声明为@Component。当然需要@Data
【解决方案2】:

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

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

当使用SpringBootTest 或任何切片测试时,它将使用任何带注释的内容,或在测试上下文中的主SpringBootApplication 中定义的bean。

【讨论】:

    【解决方案3】:

    您还需要将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;
        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-12-13
      • 2017-09-25
      • 2018-01-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-31
      • 2016-03-03
      相关资源
      最近更新 更多