SpringBoot使用powermock来mock静态方法
mock静态方法
SpringBoot使用powermock来mock静态方法的时候会碰到各种异常,下面是常见的几个:
- org.powermock.api.mockito.ClassNotPreparedException
- java.lang.Exception: Method XXX should be public
- Caused by: java.lang.NoSuchMethodException: XXX.()
下面就如何使用powermock,避免问题说明如下:
在测试类上添加 @RunWith
@RunWith(PowerMockRunner.class)
在测试类上添加 @PrepareForTest 标注静态类
@RunWith(PowerMockRunner.class)
@PrepareForTest( { UploadPathConfig.class })
class UploadImageLocalImplTest {
...
}
UploadPathConfig是要mock的有静态方法的类。
测试代码里mock静态方法
@Test
public void uploadStream() {
PowerMockito.mockStatic(UploadPathConfig.class);
PowerMockito.when(UploadPathConfig.getValue(MediaConfig.IMAGE_UPLOAD_PATH_KEY)).thenReturn(System.getProperty("user.dir") + "/images/");
......
}
第3行 mock有静态方法的类
第4行 设置调用静态方法时返回的值
之后在测试代码中调用该静态方法就会返回期望的值。
测试类添加加公有的无参数构造函数
public UploadImageLocalImplTest() {
}
测试类要显式的增加这个构造函数,否则运行单元测试时会报异常 java.lang.Exception: Test class should have public zero-argument constructor
测试方法前面要加public
@RunWith(PowerMockRunner.class)
@PrepareForTest( { UploadPathConfig.class })
class UploadVideoLocalImplTest {
@Test
public void uploadStream() {
....
}
用idea在SpringBoot工程里自动生成测试类时,测试方法前面没有public,需要手工加public,否则运行单元测试会出现这个异常:
java.lang.Exception: Method uploadStream should be public
测试方法用junit的@Test
SpringBoot自动生成的测试类使用的是org.junit.jupiter.api.Test,与powermock不兼容,我们需要改成 org.junit.Test,否则会出现异常:
org.powermock.api.mockito.ClassNotPreparedException
import org.junit.Test;
//import org.junit.jupiter.api.Test;
Maven依赖
最后,版本依赖很关键,如果版本不兼容,会出现各种异常,解决起来很头疼。下面是我使用的能够正常工作的版本。
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>2.0.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito2</artifactId>
<version>2.0.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
<scope>test</scope>
</dependency>