使用powermock的@PrepareForTest注解导致java.lang.NullPointerException的解决办法

在使用powermock时,要测试的类里有@Autowired方式注入的dao类,同时我还要mock这个类里的私有方法,所以使用了powermock的@PrepareForTest注解,但是在加上@PrepareForTest注解后,原本mock的dao类,在test时,报了java.lang.NullPointerException,mock的dao没有注入成功,不明白是否是powermock的bug,最后只能通过另外一种方式来将dao注入到要测试的类里,如下:

   /**
     * @InjectMocks 声明这个对象中的属性会被自动注入进来, 也就是下面 mock 出来的 userService
     * 注意这里说的 mock 出来的对象, 包括 @Mock 和 @Spy 声明的对象
     */
    @InjectMocks
    private ContractBillService contractBillService;

    /**
     * 使用 @Mock 生成的类, 所有方法都不是真实的方法, 而且返回值都是NULL.
     * 与之对应的还有个 @Spy
     * 使用 @Spy 生成的类, 所有方法都是真实方法, 返回值都是和真实方法一样的
     */
    @Mock
    private ConContractBillDao conContractBillDao;

    @Mock
    private ConContractBillDetailDao conContractBillDetailDao;

    @Test
    @PrepareForTest(ContractBillService.class)
    public void testConNewSignBill_success() throws Exception {
        String contractGuid = "1";
        // 这里录制脚本
        // 当我们对 @Mock 的类进行模拟方法时, 会像下面这样去做:
        // when(userService.loadUserById(any(String.class))).thenReturn(Optional.of(mockUser));
        // 当我们对 @Spy 的类进行模拟方法时, 会像下面这样去做:
        // doReturn(Optional.of(mockUser)).when(userService).loadUserById(any(String.class));
        when(conContractBillDao.deleteAny(any(ConContractBill.class))).thenReturn(1);
        when(conContractBillDetailDao.deleteAny(any(ConContractBillDetail.class))).thenReturn(1);

        // mock私有方法
        ContractBillService spy = PowerMockito.spy(contractBillService);
        ReflectionTestUtils.setField(spy, "conContractBillDao", conContractBillDao);
        ReflectionTestUtils.setField(spy, "conContractBillDetailDao", conContractBillDetailDao);
        doNothing().when(spy, "caleFirstPayBill", any(), any(), any());
        doNothing().when(spy, "caleScheduleBill", any(), any(), any(), any());
        doNothing().when(spy, "caleDepositBill", any(), any());

        // 执行你的逻辑
        Response<Void> response = spy.conNewSignBill(contractGuid);

        // 断言
        assertThat(response.getCode(), is(IResultCode.SUCCESS));
    }

其中起主要作用的就是:

ReflectionTestUtils.setField(spy, "conContractBillDao", conContractBillDao);
ReflectionTestUtils.setField(spy, "conContractBillDetailDao", conContractBillDetailDao);

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值