Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何为Spring Boot应用程序中用@Configuration注释的类编写单元测试用例_Spring_Spring Boot_Junit_Spock_Spring Boot Test - Fatal编程技术网

如何为Spring Boot应用程序中用@Configuration注释的类编写单元测试用例

如何为Spring Boot应用程序中用@Configuration注释的类编写单元测试用例,spring,spring-boot,junit,spock,spring-boot-test,Spring,Spring Boot,Junit,Spock,Spring Boot Test,我有一个配置类,它为RedissonClient创建bean,还创建CacheManager。如何为此配置类创建单元测试用例 我们可以为@Configuration类编写单元测试用例吗 如果可以,我们需要如何发展 我更喜欢使用Groovy在Spock框架中编写测试用例。如果不是,则使用Junit或Mockito框架。如何为Spring Boot应用程序中用@Configuration注释的类编写单元测试用例 @Configuration public class CacheConfigurati

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

  • 我们可以为
    @Configuration
    类编写单元测试用例吗
  • 如果可以,我们需要如何发展 我更喜欢使用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);
        }
    
    }
    
    @配置
    公共类缓存配置{
    私有静态最终字符串CONFIG=“Configuration”;
    @值(${redis.server.url}”)
    私有字符串地址;
    @值(${redis.server.password}”)
    私有字符串密码;
    @豆子
    公共RedissonClient RedissonClient(){
    Config=new Config();
    config.useSingleServer().setAddress(redisUrl).setPassword(password);
    RedissonClient=Redisson.create(配置);
    返回客户;
    }
    @豆子
    公共缓存管理器redissonCacheManager(RedissonClient RedissonClient){
    Map config=newhashmap();
    config.put(config,新缓存配置(24*60*1000,12*60*1000));
    返回新的RedissonSpringCacheManager(redissonClient,配置);
    }
    }
    
    我认为您应该意识到用
    @Configuration
    注释的类不是真正的java类,或者至少您不应该这样对待它们。我知道这听起来有争议,我会解释

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

    我想在Spring2.5中,他们引入了一种基于注释的方法,在类上放置注释
    @Component
    /
    @Service
    ,将
    @Autowired
    放置在希望spring注入依赖项的任何位置,然后spring启动,扫描类路径,检测bean并用这些bean启动应用程序上下文

    然后,Spring3.0引入了一种Java配置方式来进行与Spring相关的配置:
    @Configuration/@Bean
    在一个特殊的类中

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

    现在让我问一下,您认为您应该单独测试XML和XMLBean配置吗?可能不是。。。 你认为你应该测试这个类是否有注释
    @组件
    ,并且所有必要的依赖项都是自动连接的(带有反射或其他什么)?可能不会

    那么为什么要测试Java配置类呢?

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

    我已经说过,这些类仅用于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()); }
    
    } 
    
    注意,我们在
    B
    C
    的定义中调用
    a()
    现在,让我问你一个问题:如果它是一个“常规”java代码,那么方法
    a()
    (在B和C的构造函数中)的两个不同调用如何分别返回
    a
    的相同实例

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

    我相信还有更多类似的争论,但问题很清楚——不要单独测试配置类

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


    在代码覆盖率方面-IMO您应该将这些类完全排除在覆盖范围之外

    经过一些研究发现,我们可以运行嵌入式redis服务器,我们可以通过启动应用程序来检查是否能够连接到redis服务器。我不知道这是否正确。但这样做确实需要时间,大约需要20秒。使用以下依赖项来测试此// testCompile组:“it.ozimov”,名称:“嵌入式redis”,版本:“0.7.2”

    @SpringBootTest(classes = [TestApp])
    class CacheConfigurationSpec extends Specification {
    
    @Shared
    RedisServer redisServer;
    
    def setupSpec() {
        redisServer = RedisServer.builder()
                .port(6379)
                .setting("bind 127.0.0.1")
                .setting("maxmemory 128M")
                .build()
        redisServer.start()
    }
    
    def cleanupSpec() {
        if (redisServer != null) {
            redisServer.stop()
        }
    }
    
    @Autowired
    private RedissonClient redissonClient;
    
    def "load all contexts"() {
    
    }
    }
    @SpringBootApplication
    class TestApp {
     static void main(String[] args){
        SpringApplication.run(TestApp.class, args)
     }
    }
    

    孤立地测试它们并没有真正意义,因为它们只在Spring应用程序中有意义。我同意,假设我们用其他逻辑构建了一个应用程序,那么我们需要如何确保使用@Configuration注释的类被覆盖。您可以像任何其他类一样对其进行单元测试,即调用其公共方法并验证结果,例如,
    redissonClient()
    实际返回一个具有预期配置的
    RedissonClient
    实例。如果您想测试私有成员的值,这将是一个集成测试,您也可以轻松编写。但是问问你自己,你是真的想测试你的应用程序还是Spring容器可以工作。@kriegaex你能检查我的答案,并提出我的建议吗answer@m-戴纳姆:你能检查一下我的答案,并建议我的答案吗?–:谢谢你提供的信息,非常有用。但我确实看到一些人开发了Groovy测试用例,他们在其中启动了spring应用程序。正如您所说的将运行spring容器的集成测试,如果我必须为上面的配置执行操作,那么它们将是我必须执行的操作。我对此一无所知。斯波克是在junit4的基础上构建的junit。因此,您可以将其集成到