PowerMockito的使用

测试环境准备 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");

 

猜你喜欢

转载自blog.csdn.net/qq_41988225/article/details/107382177
今日推荐