Powermock使用笔记

powermock使用
  • mock与spy 的区别
    • 语法的区别:
      Test ms = PowerMockito.mock(Test.class);
      Test ms = PowerMockito.spy(new Test());
    • Mock对象的区别:
      mock方法生成的对象为一个空对象,即里面所有的方法均被mock了,所以在调用该对象里面的方法
      时候,均不会执行该方法,仅会返回方法返回值的零值。
      spy方法生成的对象是一个真实的对象,即调用该对象里面的方法时,会实际执行方法中的内容。
    • 使用场景的区别:
      mock方法一般比较适合用于测试类的方法需要全部被mock的情况,而spy方法适合用于测试类中方法
      部分被mock的情况。
  • 公有方法mock
    • 有返回值
      PowerMockito.doReturn(result).when(dungeonService).enterDungeonPoint(role, dungeonType, pointId);
      PowerMockito.when(forgeManager.haveForgeMaterialOnDesk(forge)).thenReturn(true);
    • 无返回值
      PowerMockito.doNothing().when(dungeonService).enterDungeonPoint(role, dungeonType, pointId);
    • 对于任意参数均mock
      PowerMockito.doReturn(result).when(dungeonService).enterDungeonPoint(Mockito.any(Role.class), Mockito.any(EnumDungeonType.class), Mockito.anyString());
    • 注意:
      1. 方法的入参要与实际执行的入参要完全相同,否则mock失败,可以理解为此方法的mock为仅参数
        为所传的参数时的方法按照预期返回对应的值,其他情况均执行方法。
      2. doNothing()仅仅对void返回的方法有效,其他有返回值的方法不可使用
  • 私有方法mock
    1. 准备:测试类继承PowerMockTestCase,测试类添加注解,注解的大括号中为被测试私有方法的类,
      @PrepareForTest({UniqueService.class})
    2. mock: PowerMockito.doNothing().when(uniqueService, "checkActivateUniqueCondition", role, uniqueType);
    3. 调用:私有方法使用反射的方法调用:boolean res = Whitebox.invokeMethod(heroService, “checkLevel”, obj, heroLevel);
  • 静态方法mock
    1. 准备:测试类继承PowerMockTestCase,测试类添加注解,注解的大括号中为被测试静态方法的类,
      @PrepareForTest({UniqueService.class}),PowerMockito.mockStatic(UniqueService.class)
    2. mock: 由于mockStatic方法的作用,该类中所有的方法均被mock,方法返回的值是对应的零值,对于有些需要指定返回值的情况可以使用:
      PowerMockito.when(MasterstrokeService.class,"getShopEventWithPoint",position).thenReturn(shopEvent);
      PowerMockito.when(MasterstrokeService.getShopEventWithPoint(position)).thenReturn(shopEvent);(推荐)
    3. 需要真实执行:对于有些方法不想被mock,而整个类被已经被mock的情况:
      PowerMockito.doCallRealMethod().when(MasterstrokeService.class, "checkInitShop", role, eventId, pos);
      (公有方法:PowerMockito.doCallRealMethod().when(forgeService).syncClientData(this.role, record);
      PowerMockito.when(MasterstrokeService.getLineTagByPoint(startPoint, endPoint)).thenCallRealMethod();(when中必须有返回值)
  • 单元测试的验证
    1. 验证结果与预期相同:
      assertEquals(baseException.getType(), result);
    2. 验证方法是否被执行
      PowerMockito.verifyPrivate(MasterstrokeService.class,Mockito.atLeastOnce()).invoke("methodName", param1, param2);
      Mockito.verify(forgeTaskManager, Mockito.atLeastOnce()).sendTaskReward(param1, param2);
  • 测试中的其他需求
    1. 需要mock被mock的对象中的一个成员时:
      forgeManager = PowerMockito.mock(ForgeManager.class);
      forgeService = PowerMockito.mock(ForgeService.class);
      Whitebox.setInternalState(forgeService, "forgeManager", forgeManager);
      保证forgeService调用forgeManager的对象时是被mock的。否则可能导致mock失败,forgeService的中的forgeManager对象与实际使用
      的不一致。
    2. 希望方法执行中某些new生成的对象为指定的对象时:
      Random random = PowerMockito.spy(new Random());
      PowerMockito.whenNew(Random.class).withAnyArguments().thenReturn(random);
      PowerMockito.doReturn(ranData).when(random, "nextFloat");
技术拓展
  • Mockito.any()仅仅可以匹配一些对象类型,包括String类型而不能匹配基本类型,基本类型需要使用对应的Mockito方法,如int则使用Mockito.anyInt()
  • mock方法时,要求要么统一使用具体的值,要么统一使用any匹配,不能部分参数是具体值,而另一部分使用mockito.any之类的匹配。
  • 有这样一个需求:mock方法时,有部分的入参不关心,或者该参数构造很麻烦,而另一部分参数需要使用具体的值,那么对于不关心的使用Mockito.any之类,而对于具体值可以使用Mockito.eq(value)(value是具体的数值,如果是对象,则必须是相同的对象(即引用相同))。
  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值