专栏首页用户1337634的专栏设置Spring单元测试的外部依赖

设置Spring单元测试的外部依赖

单元测试中,有时候也依赖外部的组件,比如Redis-Mock。Spring Boot Test需要在上下文启动之前,先启动Redis-Mock,否则上下文会启动失败

依赖的外部组件

比如单元测试中依赖redis-mock,就必须在Spring上下文下载之前就先启动Redis Server,否则就会报下面的错误

io.netty.channel.AbstractChannel$AnnotatedConnectException: 
Connection refused: no further information: localhost/127.0.0.1:6379

方法一:在每个Specification中配置RedisServer

@SpringBootTest
@ActiveProfiles("unittest")
@Transactional
class OrderManagerTest extends Specification {
    private static RedisServer redisServer = null

    def "setupSpec"() {
        try {
            redisServer = RedisServer.newRedisServer()
            redisServer.start()
            System.setProperty("spring.redis.port", Integer.toString(redisServer.getBindPort()))
        } catch (IOException e) {
            throw new RuntimeException(e)
        }
    }

    def "cleanupSpec"() {
        if (redisServer != null) {
            redisServer.stop()
        }
    }
}

更好的方法

上面方法,需要在每个Specification都配置Redis Server,存在大量的冗余。其实可以利用BeanFactoryPostProcessorApplicationListener接口实现

import com.github.tenmao.redismock.RedisServer;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ApplicationContextEvent;
import org.springframework.context.event.ContextClosedEvent;
import org.springframework.stereotype.Component;

import java.io.IOException;

@Component
public class UnittestCustomContext implements BeanFactoryPostProcessor, ApplicationListener<ApplicationContextEvent> {
    private static RedisServer redisServer = null;

    @Override
    public void onApplicationEvent(ApplicationContextEvent event) {
        if (event instanceof ContextClosedEvent) {
            //Spring上下文结束后清理自定义上下文
            System.out.println("tenmao unit test for event: " + event);
            if (redisServer != null) {
                redisServer.stop();
            }
        }
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        try {
            //Spring上下文初始化之前 配置自定义上下文,也可以修改Spring配置信息
            redisServer = RedisServer.newRedisServer();
            redisServer.start();
            System.setProperty("spring.redis.port", Integer.toString(redisServer.getBindPort()));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Spring Cloud Gateway快速体验

    GlobalFilter只要注册到Spring容器,就可以应用在所有请求,比如监控请求耗时

    十毛
  • Feign统一设置header

    Feign可以通过实现接口feign.RequestInterceptor,完成对feign.RequestTemplate的修改,比如添加header

    十毛
  • Spring --- 你真的明白Spring上下文之间的关系吗?

    WebApplicationContext 是MVC Context的父上下文,是否可以互相注入对方的bean? WebApplicationContext中...

    十毛
  • Java中使用线程时,请不要忘记Spring TaskExecutor组件

    当我们实现的web应用程序需要长时间运行一个任务时,Spring TaskExecutor管理组件是一个很好选择,会给我们代码的实现提供很大的方便,也会节省时间...

    用户1289394
  • Spring boot with Hessian

    节选自《Netkiller Java 手札》一书 5.20. Spring boot with Hessian 5.20.1. Maven <depende...

    netkiller old
  • 谷歌跨界音乐圈:AI用上千乐器数据创造出人类没听过的声音,来听听看!

    大数据文摘
  • GEF入门实例_总结_04_Eclipse插件启动流程分析

    这6个文件对RCP应用程序而言非常重要,可能我们现在对这几个文件的理解还是云里雾里,这一节我们将通过这几个文件来了解Eclipse插件的启动过程。

    shirayner
  • SpringCloud系列使用Eureka进行服务治理

    “微服务”一词来自国外的一篇博文,网站:https://martinfowler.com/articles/microservices.html

    用户1208223
  • Spring Cloud微服务之 sleuth+zipkin日志聚合

    在微服务架构中,要完成一个功能,通过Rest请求服务API调用服务来完成,整个调用过程可能会聚合多个后台服务器协同完成。在整个链路上,任何一处调用超时

    java架构师
  • rabbitMQ实现可靠消息投递 原

        RabbitMQ消息的可靠性主要包括两方面,一方面是通过实现消费的重试机制(通过@Retryable来实现重试,可以设置重试次数和重试频率,但是要保证幂...

    chinotan

扫码关注云+社区

领取腾讯云代金券