大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。
Jetbrains全家桶1年46,售后保障稳定
mockito框架上手非常简单,但是它也有弊端和局限性,不能mock静态方法、私有方法、构造方法等,但powermockito框架很好的弥补了这一缺陷。
版本说明
一般powermockito和mockito配合来使用,有相应的版本要求。
powermockito
mockito
1.6.5+
2.0.0-beta – 2.0.42-beta
1.10.19
1.6.4
1.10.8 – 1.10.x
1.6.2+
1.9.5-rc1 – 1.9.5
1.5.0 – 1.5.6
1.9.0-rc1 & 1.9.0
1.4.10 – 1.4.12
1.8.5
1.3.9 – 1.4.9
1.8.4
1.3.7 & 1.3.8
1.8.3
1.3.6
1.8.1 & 1.8.2
1.3.5
1.8
1.3
1.7
1.2.5
pom配置文件
org.powermock
powermock-module-junit4
2.0.0
test
org.powermock
powermock-api-mockito2
2.0.0
test
mock静态方法
什么时候mock静态方法?比如一个类中有许多的public方法,也有static方法,在static方法中调用static方法,但我们并不想mock静态方法中的任何代码,就需要给这个static方法mock一个返回值,mockito框架就无能为力了,因为它并不能mock静态方法,所以需要配合powermockito框架来使用,如下:
被测试方法
/**
* mock静态方法 isTrue
*/
@GetMapping(value = “/verifyStaticMcok”)
public boolean verifyStaticMcok() {
String str = “zhangsan”;
boolean flag = isTrue(str);
log.info(“校验姓名:” + flag);
return flag;
}
/**
* 静态方法
*
* @param userName 用户名不能为空
*/
public static boolean isTrue(String userName) {
return StringUtils.isNotBlank(userName);
}
测试方法
测试类上加两个注解,@PrepareForTest可以是class数组。
@RunWith(PowerMockRunner.class)
@PrepareForTest(UserSourceController.class)
public class UserSourceControllerTest {
// ……
}
测试启动前,首先mock出静态方法。
@Before
public void setUp() {
mockStatic(UserSourceController.class);
when(UserSourceController.isTrue(any(String.class))).thenReturn(true);
}
正常写测试用例就可以了。
/**
* mock静态方法
*/
@Test
public void verifyStaticMcok_success() {
boolean flag = userSourceController.verifyStaticMcok();
assertTrue(flag);
}
mock私有方法
查了很多资料,网上答案如出一辙,个人感觉private方法不应该被mock,既然是私有的它也属于本类中代码的原有的一部分,那应该让它走完得出结果,但powermock依然可以做到(通过反射)。什么时候使用?跟静态方法的使用场景一样。
被测试方法
/**
* mock私有方法
*
* @param userName 用户名
*/
@GetMapping(value = “/verifyPrivateMethod”)
public String verifyPrivateMethod(String userName) {
log.info(“传入的用户名:” + userName);
String result = getUserName(userName);
return result;
}
/**
* 私有方法
*
* @param str 传入参数
*/
private String getUserName(String str) {
log.info(“进入了私有方法” + str);
return str;
}
测试方法
测试类上加两个注解,@PrepareForTest可以是class数组。
@RunWith(PowerMockRunner.class)
@PrepareForTest(UserSourceController.class)
public class UserSourceControllerTest {
// ……
}
注释写在了代码里。
/**
* mock私有方法
*/
@Test
public void verifyPrivateMethod_success() throws Exception {
// spy被测类,只有被spy出来的类,才可以对私有方法进行mock
UserSourceController spy = PowerMockito.spy(new UserSourceController());
// 模拟私有方法(反射),意思是传入”zhangsan”,强制返回”laozheng”
// 方法原型: public static OngoingStubbing when(Object instance, String methodName, Object… arguments) throws Exception;
PowerMockito.when(spy, “getUserName”, “zhangsan”).thenReturn(“laozheng”);
String userName = spy.verifyPrivateMethod(“zhangsan”);
// 验证私有方法被执行了
PowerMockito.verifyPrivate(spy, Mockito.times(1)).invoke(“getUserName”, “zhangsan”);
assertEquals(“laozheng”, userName);
}
总结
为什么mockito不能mock静态方法?mockito使用继承的方式实现mock的,用CGLIB生成mock对象代替真实的对象进行执行,为了mock实例的方法,你可以在子类中覆盖它,而static方法是不能被子类覆盖的,所以mockito不能mock静态方法。但powermock可以mock静态方法,因为它直接在字节码上工作。
@PrepareForTest必须写在类上,不能写到具体的测试方法上否则会报错:java.lang.Exception: No tests found matching Method。
补充
更新于2020年5月21日
mock HttpServletRequest
@Test
public void integration_test() throws ServiceException {
MockHttpServletRequest mockHttpServletRequest = new MockHttpServletRequest();
mockHttpServletRequest.addHeader(“password”, “123456”);
WalletHRGrantReq walletHRGrantReq = buildWalletHRGrantReq();
BaseResponse baseResponse = walletHRController.integration_unencrypted(walletHRGrantReq, mockHttpServletRequest);
verify(walletHRBusiness, times(1)).dealRequest(any(WalletHRGrantReq.class));
verify(redisLockService, times(1)).lock(any(String.class), any(Long.class), any(Long.class));
// 实际值#期望值
assertThat(baseResponse.getCode(), is(“200”));
}
更新于2020年7月14日
mock RestTemplate
JSONObject jsonObject = restTemplate.postForObject(processInstanceUrl, httpEntity, JSONObject.class);
类似这种的,可以这样写:
when(restTemplate.postForObject(any(String.class), any(HttpEntity.class), eq(JSONObject.class))).thenReturn(mockJSONObject());
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/219113.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...