使用PowerMock mock方法内局部变量不生效问题求解
问题根因
两次mock不生效的核心原因是两个常见使用错误:
- 第一版mock逻辑完全拦错了对象:
HttpResponse实例不是通过new HttpResponse()构造生成的,是链式调用末尾asJson()方法的返回值,用whenNew(HttpResponse.class)根本拦截不到这个对象的生成,自然不会生效。 - 第二版mock
HttpRequestWithBody时报错,原因有二:- 没有正确配置Powermock拦截规则:使用
whenNew拦截构造方法时,必须在测试类上加@PrepareForTest(包含sendAddTaskResult方法的业务类.class)注解,同时用PowerMockRunner作为测试执行器,否则拦截逻辑完全不生效。 - 链式调用打桩写法错误:直接在
when()里串联.header().fields().asJson()的写法会触发空指针——Mockito生成的mock对象默认所有方法返回值为null,没有提前给每一步的返回值打桩的话,前一个方法拿到null再调用后续方法必然抛异常。
- 没有正确配置Powermock拦截规则:使用
正确实现步骤
- 第一步:给测试类加必要的Powermock注解
@RunWith(PowerMockRunner.class) // 注意:这里填写你自己定义sendAddTaskResult方法的业务类,不是第三方HTTP请求类 @PrepareForTest(TaskService.class) public class TaskServiceTest { // 测试逻辑写在这里 }
- 第二步:按调用链路逐层打桩,不要直接在when参数中写连续链式调用
@Test public void testSendAddTaskResult() throws Exception { // 1. 构造最终要返回的mock响应 HttpResponse mockResponse = mock(HttpResponse.class); when(mockResponse.getStatus()).thenReturn(200); // 2. mock链式调用中间的MultipartBody对象 MultipartBody mockMultipartBody = mock(MultipartBody.class); when(mockMultipartBody.asJson()).thenReturn(mockResponse); // 3. mock请求对象,逐个配置方法返回值 HttpRequestWithBody mockRequest = mock(HttpRequestWithBody.class); when(mockRequest.header(anyString(), anyString())).thenReturn(mockRequest); when(mockRequest.fields(any(Map.class))).thenReturn(mockMultipartBody); // 4. 拦截业务代码中new HttpRequestWithBody的逻辑 whenNew(HttpRequestWithBody.class).withAnyArguments().thenReturn(mockRequest); // 实例化业务对象,调用待测方法做断言即可 TaskService service = new TaskService(); service.sendAddTaskResult(); // 后续编写自己的业务断言逻辑 }
额外优化提示
如果request对象不是sendAddTaskResult方法内部new出来的局部变量,而是业务类的成员变量,完全不需要用whenNew拦截构造:直接用@Mock生成mock请求对象,再通过@InjectMocks注入到业务类实例中即可,配置更简单,也不会触发构造拦截的相关异常。
你之前单独封装的anyParameters()方法没有必要,直接使用Mockito.any(Map.class)做参数匹配即可,不会出现类型匹配问题。
内容的提问来源于stack exchange,提问作者mochi
相关产品推荐
相关产品推荐

