类StaticBlockService包含一个静态块,该静态块中语句执行必然报异常导致类初始化失败。
@Service
public class StaticBlockService {
static {
int a = 1 / 0;
}
public void test() {
}
}
另一个类TestService引用StaticBlockService ,由于StaticBlockService 初始化失败,TestService也无法正常初始化。
@Service
public class TestService {
@Resource
private StaticBlockService staticBlockService;
public void runTest() {
staticBlockService.test();
}
}
那么,如何在UT中mock StaticBlockService 的静态块保证测试方法正确执行?
public class TestServiceTest {
@Tested
private TestService testService;
@Injectable
private StaticBlockService staticBlockService;
@Test
public void testTest() {
testService.runTest();
}
}
解决方案如下
public class TestServiceTest {
@Tested
private TestService testService;
@Injectable
private StaticBlockService staticBlockService;
// BeforeClass保证在加载StaticBlockService前执行before方法
@BeforeClass
public static void before() {
new MockUp<StaticBlockService>() {
@Mock
void $clinit() {
// clinit是jvm用来初始化静态变量和静态块的方法
}
};
}
@Test
public void testTest() {
testService.runTest();
}
}
即mock掉jvm执行静态块代码和初始化静态变量的clinit方法。
注意使用@BeforeClass保证在StaticBlockService初始化前即clinit方法执行前执行mock。