如何Mock ContainerRequestContext?Mockito无法Mock该接口问题求助
为何无法Mock ContainerRequestContext?
问题背景
需要Mock ContainerRequestContext 以从资源类获取HttpMethod(POST、GET、PATCH)及用户会话,但运行测试时抛出Mock无法创建的异常。相关代码如下:
Resource.java
@POST @Produces("application/json") @RightsFilter public Response create(JsonObject jsonObject, @Context UriInfo uriInfo, @Context final SecurityContext context) { // 业务代码 return Response.status(Status.OK) .entity(entity) .type(MediaType.APPLICATION_JSON).build(); }
RightsFilterTest.java
private ContainerRequestContext requestContext; private SecurityContext securityContext; @Before public void setup(){ requestContext = mock(ContainerRequestContext.class); securityContext = mock(SecurityContext.class); } @Test public void abort() throws Exception{ when(requestContext.getMethod()).thenReturn(Resource.class.getMethod("POST").toString()); }
抛出异常
org.mockito.exceptions.base.MockitoException: Mockito cannot mock this class: interface javax.ws.rs.container.ContainerRequestContext. Mockito can only mock non-private & non-final classes. If you're not sure why you're getting this error, please report to the mailing list.
使用工具版本:JUnit4.12、mockito-core-2.13.0
原因分析及解决办法
1. Mockito版本与依赖缺失
Mockito 2.x版本中,默认的mockito-core对部分系统级接口(如JAX-RS的ContainerRequestContext)的Mock支持存在限制,尤其是当接口由系统类加载器加载时,Mockito无法生成代理类。
解决办法:
- 添加
mockito-inline依赖:该模块专门用于支持Mock接口、final类及系统类加载器加载的类。以Maven为例:<dependency> <groupId>org.mockito</groupId> <artifactId>mockito-inline</artifactId> <version>2.13.0</version> <scope>test</scope> </dependency> - 升级Mockito版本:建议升级到3.x及以上版本,新版本对接口Mock的兼容性更好,
mockito-inline的集成也更完善。
2. 类加载器冲突
ContainerRequestContext属于JAX-RS API包,如果该包被标记为provided范围(常见于Web项目),测试环境下类加载器无法正确加载该接口,导致Mockito无法创建代理。
解决办法:
- 调整JAX-RS API依赖的范围为
test或compile,确保测试时可以访问到接口的类文件。以Maven为例:<dependency> <groupId>javax.ws.rs</groupId> <artifactId>javax.ws.rs-api</artifactId> <version>2.1.1</version> <scope>test</scope> </dependency>
3. 改用Jersey测试框架
如果只是为了测试JAX-RS过滤器或资源类,推荐使用Jersey自带的Test Framework,它可以模拟完整的请求上下文,无需手动MockContainerRequestContext。
核心思路:
- 引入
jersey-test-framework依赖,编写测试类继承JerseyTest,配置资源和过滤器后,直接发送模拟请求即可获取真实的请求上下文。
内容的提问来源于stack exchange,提问作者BEN
相关产品推荐
相关产品推荐

