单元测试中,有时候也依赖外部的组件,比如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,存在大量的冗余。其实可以利用BeanFactoryPostProcessor
和ApplicationListener
接口实现
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);
}
}
}
网友评论