做单元测试时,遇到过这样一个问题,代码如下:
public class RedisClient {
protected static final redisClientImpl jedisClient;
static {
redisClient = new RedisClientImpl("redis.conf");
}
}
public class RedisClientImpl{
//构造方法
public RedisClientImpl(String configPath) {
super(configPath);
init();
}
}
测试类:
PowerMockito.mockStatic(RedisClient.class);
PowerMockito.when(RedisClient.getListStrFromJedis(Matchers.any(String.class))).thenReturn(commdcList);
通过这种方式打桩时,而且打桩时,会默认加载RedisClient 到内存里,加载静态代码块,redisClient = new RedisClientImpl("redis.conf");会默认加载配置文件,连接zk等,从而不停循环连接导致报错,无法打桩,后来考虑俩种方式:1、通过反射,但反射也是运行后才加载,验证不成功。2、通过继承,但jedisClient为final类型,验证失败。
最后,想到了在RedisClient的上一层进行打桩,即静态块里的实现类RedisClientImpl的实例。反正目的是让程序不加载配置文件。如下:针对构造方法进行打桩。
PowerMockito.whenNew(RedisClientImpl.class).withArguments(Matchers.any(String.class)).thenReturn(null);
PowerMockito.mockStatic(RedisClient.class);
PowerMockito.when(RedisClient.getListStrFromJedis(Matchers.any(String.class))).thenReturn(commdcList);
于是完美,搞定