Spring测试静态方法打桩-PowerMockito及SpringBootTest结合使用
程序员文章站
2022-07-14 10:25:31
...
Mockito无法对静态方法进行Mock,如果需要Mock静态方法,需要使用到PowerMockito。
1. Maven依赖
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito</artifactId>
<version>1.7.1</version>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>1.7.1</version>
</dependency>
2. 单元测试
单元测试时,需要使用PowerMockRunner及PrepareForTest两个注解:
@RunWith(PowerMockRunner.class)
@PrepareForTest({SysCache.class})
public class ModelAssistantServiceUTTest {
private ModelAssistantService modelAssistantService;
private ModelAssistantDao modelAssistantDao;
private String tenantId;
private String deviceTypeId;
@Before
public void before() throws NoSuchFieldException, IllegalAccessException {
modelAssistantService = new ModelAssistantServiceImpl();
modelAssistantDao = MockUtil.mockField(ModelAssistantServiceImpl.class,
modelAssistantService, "modelAssistantDao", ModelAssistantDao.class);
this.tenantId = "158";
this.deviceTypeId = "3000";
// SysCache打桩
PowerMockito.mockStatic(SysCache.class);
PowerMockito.when(SysCache.getTargetDbCache(BDDMockito.anyLong(), BDDMockito.anyString(), BDDMockito.any()))
.thenReturn(new TargetDB());
}
}
如果不使用PrepareForTest,将会报以下错误:
... not prepared for test.
而使用PrepareForTest注解时,必须要使用PowerMockRunner才会生效!
3 与SpringBootTest一起使用
SpringBootTest必须要使用SpringRunner才能生效;但RunWith没有办法指定多个,可以通过PowerMockRunnerDelegate来解决这个问题:
@RunWith(PowerMockRunner.class)
@PowerMockRunnerDelegate(SpringRunner.class)
@PrepareForTest(HttpRequest.class)
@SpringBootTest
单单添加了以上四个注解还是不够,在执行的时候会报以下错误:
java.lang.LinkageError: loader constraint violation: loader (instance of org/powermock/core/classloader/MockClassLoader) previously initiated loading for a different type with name "javax/management/MBeanServer"
此时需要通过PowerMockIgnore注解来解决:
@PowerMockIgnore( {"javax.management.*"})
再次执行,发现又报以下错误:
Caused by: java.security.NoSuchAlgorithmException: class configured for SSLContext: sun.security.ssl.SSLContextImpl$TLSContext not a SSLContext
需要在PowerMockIgnore再添加一个忽略项:
@PowerMockIgnore( {"javax.management.*", "javax.net.ssl.*"})
因此,最终测试类上的注解如下:
@RunWith(PowerMockRunner.class)
@PowerMockRunnerDelegate(SpringRunner.class)
@PowerMockIgnore( {"javax.management.*", "javax.net.ssl.*"})
@PrepareForTest(HttpRequest.class)
@SpringBootTest
这样之后测试类终于可以成功启动了。