测试环境准备 PowerMock start
@RunWith 类前添加,可以理理解为提供测试启动环境
@RunWith(MockitoJUnitRunner.class)
@prepareForTest 类前添加。
当需要mock final⽅方法、静态⽅方法、私有⽅方法的时候,必须加注解@PrepareForTest 和
@RunWith 。注解@PrepareForTest⾥里里写的类是对应⽅方法所在的类。
@PrepareForTest({SafTraceRepository.class, SafTraceConverter.class})
@InjectMocks 生成
创建⼀一个实例例,简单的说是这个Mock可以调⽤用真实代码的⽅方法,其余⽤用@Mock(或@Spy)注解创
建的mock将被注⼊入到⽤用该实例例中,⼀一般⽤用于当前被测试的类注⼊入。
@InjectMocks
SafMessageListener safMessageListener;
@Mock 注解模拟依赖对象,⼀一般⽤用于测试类外部依赖的注⼊入。
/**
*
* safProcessService 是上述InjectMocks实例( safMessageListener )中的依赖变量,比如 @Autowired注入的
*
*/
@Mock
private BizProcessService safProcessService;
PowerMock use
普通方法stub
对注⼊入service⽅方法,以及其他公共⽅方法的stub,我们⼀一般使⽤用两种⽅方式。
//when ... thenReturn ... ⽅方法会被调⽤用,例例如selectByTunnelIdAndSts会被调⽤用
PowerMockito.when(safTraceDao.selectByTunnelIdAndSts(Mockito.any())).thenReturn(safTra
cePOS);
//doReturn ... when ... ⽅方法不不会被调⽤用,前提是stub的⽅方法是public⽅方法,如果是private⽅方法依旧会被
调⽤用
PowerMockito.doReturn(safTracePOS).when(safTraceDao.selectByTunnelIdAndSts(Mockito.any
()));
stub异常
stub时让调⽤用⽅方法抛出指定异常。
//do和then的场景相同
PowerMockito.doThrow(new RuntimeException()).when(safParaDAO.updateSafParam(safParaPO));
PowerMockito.when(safParaDAO.updateSafParam(safParaPO)).thenThrow(new RuntimeException());
对公有无返回值的mock(切记仅能⽤用此⽅方式)
PowerMockito.doNothing().when(bizExceptionService).process(safProcessDO);
spy对象
一般模拟 final⽅方法、静态⽅方法、私有⽅方法,我们需要新建spy对象。要注意调⽤用
SafMessageListener spy = PowerMockito.spy(safMessageListener);
PowerMockito.doNothing().when(spy,"sendToExceptionNode", Mockito.any(), Mockito.any(),
Mockito.any());
spy.processMessage(safReqDTO);
私有方法mock( 前提是要定义spy )
对私有无返回值⽅方法的mock(有返回值,即添加doReturn/thenReturn)
PowerMockito.doNothing().when(spy,"sendToExceptionNode", Mockito.any(),
Mockito.any(), Mockito.any());
静态方法mock
对私有静态无返回值⽅方法的mock(有返回值,即添加doReturn/thenReturn)
PowerMockito.doNothing().when(Utility.class, "doSomething", Mockito.any());
对公有静态无返回值⽅方法的mock(有返回值,即添加doReturn/thenReturn)
PowerMockito.doNothing().when(Utility.class);
Utility.doSomething(Mockito.any());
Runtime runtime = Whitebox.invokeConstructor(Runtime.class);
PowerMockito.mockStatic(Runtime.class);
PowerMockito.when(Runtime.getRuntime()).thenReturn(runtime);
测试私有方法
因为私有⽅方法不不能直接调⽤用,所以要采取以下⽅方式进⾏行行测试,利用反射:
/**
* decryptData(List<String> encryptPans)
*/
@Test
public void testDecryptData() {
try {
Method method = PowerMockito.method(BatchDecryptServiceImpl.class, "decryptData", List.class);
method.setAccessible(true);
method.invoke(batchDecryptServiceImpl, strings);
ReflectionTestUtils.setField(batchDecryptServiceImpl, "decryptKey", "decryptKey");
method.invoke(batchDecryptServiceImpl, strings);
} catch (Exception e) {
e.toString();
}
}
私有变量量mock
//safParaRepository 为当前测试的类
PowerMockito.field(SafParaRepository.class,"localCache").set(safParaRepository,loc
alCache);
注解@Value从配置文件读取的变量
@Value("${rocketmq.topic}")
private String topic;
targetObject 是@Value 所在类对象。
ReflectionTestUtils.setField(targetObject, "topic", "xxx");