使用Mockito模拟通用类型

时间:2017-04-14 16:46:20

标签: java junit jersey mockito

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

正在测试的代码

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 );
}

所以这行代码给了我一个null响应。有没有其他方法可以做到这一点。

感谢。

2 个答案:

答案 0 :(得分:0)

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

您的生产代码确实:

Entity.entity( new ByteArrayInputStream( ...

所以,你得到的是:

  • 静态电话(Entity.entity()
  • 致电new

这两项操作都不能用Mockito嘲笑。它是如此简单。

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

但我建议采用不同的解决方案:考虑重新编写生产代码。而是进行静态+新呼叫;创建像

这样的东西
interface EntityProvider {
  public Entity of(bytes[] data, MediaType type);
}

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

并且不需要考虑其他模拟框架(和imho;至少PowerMockito带来一定的成本 - 它不像&#34那么简单;只需切换到其他框架&#34;)。

答案 1 :(得分:0)

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

上面的陈述给了我模拟的回应。现在,我可以使用模拟的Response对象做任何我想做的事情。我可以模拟getStatus方法并返回状态代码或其他任何东西。

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