spring - 如何在Spring Boot应用中为@Configuration注解的类编写单元测试用例

标签 spring spring-boot junit spock spring-boot-test

我有一个配置类,它为RedissonClient 创建了bean,还创建了CacheManager。如何为此配置类创建单元测试用例。

  1. 我们可以为@Configuration 类编写单元测试用例吗?
  2. 如果可以,我们需要如何发展。

我更喜欢使用 Groovy 在 Spock 框架中编写测试用例。如果没有,请使用 Junit 或 Mockito 框架。如何在Spring Boot应用中为带有@Configuration注解的类编写单元测试用例

@Configuration
public class CacheConfiguration {
    private static final String CONFIG= "Configuration";

    @Value("${redis.server.url}")
    private String redisUrl;

    @Value("${redis.server.password}")
    private String password;

    @Bean 
    public RedissonClient redissonClient() {
        Config config = new Config();
        config.useSingleServer().setAddress(redisUrl).setPassword(password);
        RedissonClient client = Redisson.create(config);
        return client;
    }
    @Bean
    public CacheManager redissonCacheManager(RedissonClient redissonClient) {
        Map<String, CacheConfig> config = new HashMap<String, CacheConfig>();
        config.put(CONFIG, new CacheConfig(24*60*1000, 12*60*1000));
        return new RedissonSpringCacheManager(redissonClient, config);
    }

}

最佳答案

我认为您应该意识到用@Configuration 注释的类并不是真正的java 类,或者至少您不应该这样对待它们。我知道这听起来有争议,我会解释...

所以历史上 spring 使用 XML 配置来声明 bean。

我想在 spring 2.5 中,他们引入了一种基于注释的方法,您可以在其中将注释 @Component/@Service 放在类上,将 @Autowired 在任何你希望 spring 注入(inject)依赖项的地方,然后 spring 启动,扫描类路径,检测 beans 并使用这些 beans 启动应用程序上下文。

然后 Spring 3.0 引入了一种 Java Configuration 方法来进行 spring 相关配置:@Configuration/@Bean 在一个特殊的类中。

因此您应该将这些配置类视为我之前描述的方法的“替代品”

现在让我问一下,您认为您应该自行测试和配置 XML bean 吗?可能不会... 你认为你应该测试那个类有注释 @Component 并且所有必要的依赖都是 Autowiring 的(通过反射或其他)?可能不是。

那么为什么要测试 Java Config 类?

这是您可能会感兴趣的另一个论点

我已经说过这些类仅供 spring 解析 bean 并在内部运行它们。但是 spring 不只是“运行”它们——它为它们创建了运行时包装器来克服一些技术问题。这是一个这样的例子:

以免假设我们有三个 bean:A、B、C,例如 B 和 C 依赖于 A。


class A {}

class B {
   private A a;
   public B(A a) {this.a = a;}
}

class C {
   private A a;
   public C(A a) {this.a = a;}
}

所有 bean 都应该是单例的,所以我们这样定义配置:

@Configuration
public class MyConfig { 
   @Bean
   public A a() { return new A(); }

   @Bean
   public B b() { return new B(a()); }

   public C c() {return new C(a()); }

} 

请注意,我们在 BC 的定义中调用了 a() 现在,让我问你一个问题:如果它是一个“常规”Java 代码,方法 a() 的两个不同调用(在 B 和 C 的构造函数中)分别应该如何返回相同的 A 的实例

所以 spring 确实使用了很多复杂的代码,这是在运行时实际运行的代码,不是你的类,而是它的转换版本,你永远不知道这些转换到底是什么,因为它和内部 Spring 的东西。但是,按原样对其进行测试有什么意义呢?

我相信还有更多这样的争论,但要点很明确——不要自己测试配置类。

相反,您可以使用集成测试来运行 spring 容器并加载配置中所需的所有类。但是,在这种情况下,您可能希望模拟一些类(例如通过使用 @MockBean),因此它不会是 100% 准确的测试。

就代码覆盖率而言——IMO 你应该将这些类完全排除在覆盖范围之外

关于spring - 如何在Spring Boot应用中为@Configuration注解的类编写单元测试用例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60167788/

相关文章:

javascript - 在 jBoss 6.2 和 jBoss 7.3 中部署应用程序时的不同响应

java - Spring 和带有 select 的表单

java - Spring 启动错误: Use of @OneToMany or @ManyToMany targeting an unmapped class

java - Spring Security : Why . AuthorizeRequests().antMatchers ("/api/v1/web/**").permitAll() 不起作用?

spring - REST客户端Grails Groovy无法解析类RestClientBuilder

java - 将 spring-boot 1.5 迁移到 2.0 后,Webservices 调用出现 405 错误

java - 在命令行上运行时 Spring Boot 应用程序挂起

java - 测试Apache Camel Junit的所有进程和路由

java - JUnit:比较两个无序文本文件的内容

android - 在 Eclipse 中不打断点调试 Android Junit 测试