2017-04-14 279 views
0

我正在使用JUnit和Mockito编写使用Jersey的REST服务的测试用例。我得到一个null对象而不是Response类的模拟对象。被测Mocking使用Mockito的泛型类型

代码

Response response = builder 
         .put(Entity.entity(new ByteArrayInputStream(jsonObj.toString().getBytes()), MediaType.APPLICATION_JSON), Response.class); 

测试用例:

private Invocation.Builder builder; 
private Entity<ByteArrayInputStream> inputStream; 
private Response response; 
@Before 
public void setUp() throws Exception { 
    builder = mock(Invocation.Builder.class); 
    inputStream = (Entity<ByteArrayInputStream>)mock(Entity.class); 
    response = mock(Response.class); 
} 

@Test 
public void myTest() { 
when(builder.put(inputStream, Response.class)).thenReturn(response); 
} 

所以这行代码给了我一个空的回应。有没有其他的方式来做到这一点。

谢谢。

回答

0

我已经解决了这个问题,所以我想分享一下我实际上做了什么。 Mockito.when(builder.put(any(Entity.class), any(Class.class))).thenReturn(response);

上面的声明给了我嘲笑的回应。现在我可以用模拟的Response对象做任何事情。我可以嘲笑getStatus方法并返回状态码或其他任何东西。

希望这可以帮助那些Mockito和PowerMockito Api。

0

那是因为你混合了各种各样的东西。

你的产品代码的作用:

Entity.entity(new ByteArrayInputStream(... 

所以,你得到了什么有:

  • 一个静态调用(Entity.entity()
  • 调用new

这两个操作不能被Mockito嘲笑。它是如此简单。

为了模拟静态方法调用,您必须查看框架,如PowerMock(ito)或JMockit。

但我宁愿推荐一个不同的解决方案:考虑重新生产您的生产代码。而不是静态+新的呼叫;创造这样

interface EntityProvider { 
    public Entity of(bytes[] data, MediaType type); 
} 

您可以轻松创建一个使用您的当前代码的实现类 - 但测试的目的,你可以依赖项注入该接口(通过Mockito.mock()创建)的模拟;突然之间,你的整个代码再次被Mockito测试。

无需研究其他模拟框架(至少PowerMockito带有一定的成本 - 它不像“只是切换到其他框架”那么简单)。