Java单元测试:使用PowerMockito库对方法进行进一步mock

单元测试第七篇,在第六篇中,介绍了mockito对public方法的mock,但是mockito不支持私有方法、静态方法等,因此,本文介绍PowerMockito库,它在mokito上进行增强,可以mock 静态方法、私有方法、final方法、enum、构造函数等等。

  • 注:要使用PowerMockito,必须使用org.junit.Test,且class和method都必须是public
  • 参考:https://github.com/powermock/powermock/issues/1030。
  • 相关代码已经放在Github上:源代码

特别说明:
在很多地方,都强烈建议不使用该框架,大意就是如果需要对静态方法、私有方法、构造函数等进行mock,说明你的应用架构设计不合理,应该考虑重新设计你的业务实现。


下面简述开发过程:

1、首先,还是正常建立项目,并完成一些常规的业务逻辑开发;

2、项目添加mockito库的引用,打开pom.xml,添加:

<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-core</artifactId>
    <version>3.5.13</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.powermock</groupId>
    <artifactId>powermock-module-junit4</artifactId>
    <version>2.0.7</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.powermock</groupId>
    <artifactId>powermock-api-mockito2</artifactId>
    <version>2.0.7</version>
    <scope>test</scope>
</dependency>

注1:引用的库,包含第六篇里的mockito。

3、application.yml配置文件无需修改.

4、静态方法mock:

String name = "王霸";
Assert.isTrue(BusinessService.getHello1(name).equals("Hello1, 王霸"), "原生有问题?");

PowerMockito.mockStatic(BusinessService.class);
PowerMockito.when(BusinessService.getHello1(ArgumentMatchers.any())).thenReturn("你好");
Assert.isTrue(BusinessService.getHello1("").equals("你好"), "mock有问题?");

5、构造函数mock:

BusinessService mockObj = PowerMockito.mock(BusinessService.class);
PowerMockito.when(mockObj.requestSinaHtml()).thenReturn("Mock新浪");

// 如果创建 BusinessService对象时,传递了参数 abc,则返回mock对象
PowerMockito.whenNew(BusinessService.class).withArguments("abc").thenReturn(mockObj);

// 创建对象,不符合mock条件,创建会失败
BusinessService noMock = new BusinessService("abcd");
Assert.isTrue(noMock == null, "原生方法?");

// 创建对象,符合mock条件
BusinessService withMock = new BusinessService("abc");
Assert.isTrue(withMock.requestSinaHtml().equals("Mock新浪"), "Mock方法?");

6、私有方法mock:

BusinessService mockObj = PowerMockito.spy(new BusinessService());

// 没mock前,调用原生方法
String tmp = mockObj.getHello2("ab");
Assert.isTrue(tmp.equals("Hello2, ab"), "原生有问题?");

// mock私有方法
PowerMockito.when(mockObj, "getHelloPrivate", Mockito.anyString()).thenReturn("abc");

tmp = mockObj.getHello2("ab");
Assert.isTrue(tmp.equals("abc"), "mock有问题?");

7、final方法mock:

BusinessService mockObj = PowerMockito.spy(new BusinessService());

// 没mock前,调用原生方法
String tmp = mockObj.getHelloFinal("ab");
Assert.isTrue(tmp.equals("Hello, Final ab"), "原生有问题?");

// mock final方法
PowerMockito.when(mockObj.getHelloFinal(Mockito.anyString())).thenReturn("abc");

tmp = mockObj.getHelloFinal("ab");
Assert.isTrue(tmp.equals("abc"), "mock有问题?");

8、enum枚举mock:

BusinessService.EnumDemo mockObj = PowerMockito.mock(BusinessService.EnumDemo.class);

// 没mock前,调用原生方法
String tmp = BusinessService.EnumDemo.enum2.getTitle();
Assert.isTrue(tmp.equals("ENUM2"), "原生有问题?");

// mock enum2 方法
Whitebox.setInternalState(BusinessService.EnumDemo.class, "enum2", mockObj);
PowerMockito.when(mockObj.getTitle()).thenReturn("abc");

// 返回mock后的值
tmp = BusinessService.EnumDemo.enum2.getTitle();
Assert.isTrue(tmp.equals("abc"), "mock有问题?");

// 未mock
tmp = BusinessService.EnumDemo.enum3.getTitle();
Assert.isTrue(tmp.equals("ENUM3"), "mock有问题?");

注:以上代码,在提供的源码Demo里都有。

如果你在运行时有问题,可以下载上面的源码,进行对比,看看你的代码哪里有问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

游北亮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值