JerseyTest结合Mockito模拟对象失效及匹配器错误求助
JerseyTest中Mockito模拟ServiceController失效的解决方案
1. 先搞定InvalidUseOfMatchers错误
这个错误大多是匹配器使用不规范导致的:
- 必须静态导入Mockito的所有匹配器:
import static org.mockito.Mockito.*; - 写
when语句时,要么全用匹配器,要么全用具体参数,不能混着来。比如方法参数是单个字符串,就统一用anyString()或者具体值,别一半用匹配器一半用真实字符串。 - 如果方法有多个参数,所有参数都得用匹配器,比如
returnSth(String a, int b)就得写成when(mock.returnSth(anyString(), anyInt())).thenReturn(...),不能一个参数用匹配器另一个用具体数字。
2. 正确在JerseyTest里绑定Mock对象
Jersey有自己的DI容器,光靠Mockito的注解搞不定,得把Mock实例注册到Jersey的配置里:
步骤1:初始化Mock并配置行为
手动创建Mock比依赖注解更稳妥,避免JUnit和Jersey的Runner冲突:
public class HelloTest extends JerseyTest { private ServiceController mockService; @Override public void setUp() throws Exception { // 创建Mock实例 mockService = mock(ServiceController.class); // 配置Mock返回固定值 when(mockService.returnSth(anyString())).thenReturn("RetFromMock"); super.setUp(); } }
步骤2:配置Jersey的资源绑定
重写configure方法,把Mock绑定到ServiceController类型,再注册Hello端点类:
@Override protected Application configure() { return new ResourceConfig() // 绑定Mock实例到ServiceController类/接口 .register(new AbstractBinder() { @Override protected void configure() { // 如果ServiceController是接口,就to(ServiceController.class) // 如果是具体类,同样绑定到自身类型 bind(mockService).to(ServiceController.class); } }) // 注册你的端点类 .register(Hello.class); }
之前绑定报错IllegalArgumentException,大概率是绑定的实例类型和to()里的类型不匹配——比如你绑定了一个子类实例,却to到了无关的类,或者ServiceController是接口但你to到了实现类,改对应就行。
3. 避免NullPointerException的关键
- 别指望
@InjectMocks能自动搞定Jersey管理的资源类,因为Mockito的DI和Jersey的HK2容器是两套体系,容易出现注入失败。 - 要么手动给Hello类注入Mock(比如用setter或者构造函数),要么通过上面的
AbstractBinder让Jersey自动注入,二选一就行。 - 如果非要用
@Mock注解,一定要在setUp里调用MockitoAnnotations.openMocks(this)初始化,别光加注解不管初始化。
4. 完整可运行示例
import static org.mockito.Mockito.*; import org.glassfish.jersey.server.ResourceConfig; import org.glassfish.jersey.test.JerseyTest; import org.glassfish.jersey.internal.inject.AbstractBinder; import org.junit.Test; import javax.ws.rs.core.Application; import javax.ws.rs.core.Response; import static org.junit.Assert.assertEquals; public class HelloTest extends JerseyTest { private ServiceController mockServiceController; @Override public void setUp() throws Exception { mockServiceController = mock(ServiceController.class); // 配置Mock行为,确保匹配器使用正确 when(mockServiceController.returnSth(anyString())).thenReturn("RetFromMock"); super.setUp(); } @Override protected Application configure() { return new ResourceConfig() .register(new AbstractBinder() { @Override protected void configure() { bind(mockServiceController).to(ServiceController.class); } }) .register(Hello.class); } @Test public void testHelloEndpoint() { Response response = target("/hello").request().get(); String result = response.readEntity(String.class); // 验证返回值是否符合预期 assertEquals("Hello Jerseyreturned RetFromMock", result); // 验证Mock方法是否被调用过 verify(mockServiceController).returnSth(anyString()); } }
内容的提问来源于stack exchange,提问作者lewap02
相关产品推荐
相关产品推荐

