Json 用mockito调用Rest方法

Json 用mockito调用Rest方法,json,junit,jersey,httprequest,mockito,Json,Junit,Jersey,Httprequest,Mockito,我使用Jersey,我有以下Rest函数,在部署服务器时返回JSON字符串: @GET @Path("getallemployees") @Produces("application/json") public Response getAllEmployees() { //building the entity object which is List<Employee> return Response.ok(entity).build(); } @GET @路径(“getalle

我使用Jersey,我有以下Rest函数,在部署服务器时返回JSON字符串:

@GET
@Path("getallemployees")
@Produces("application/json")
public Response getAllEmployees() {
//building the entity object which is List<Employee>
return Response.ok(entity).build();
}
@GET
@路径(“getallemployees”)
@生成(“应用程序/json”)
公众回应getAllEmployees(){
//构建实体对象,该实体对象是列表
返回Response.ok(entity.build();
}
我需要开发一些单元测试(而不是集成测试),我想以某种方式模拟调用此方法的HTTPRequest,然后获取json字符串。最好的选择是为此使用mockito

对如何做有什么建议吗


谢谢

问题在于,该方法将
响应
对象返回给调用方,调用方位于框架代码的深处。它不返回JSON字符串

如果需要模拟方法本身内部的某些内容,可以使用Mockito。这应该行得通

但是如果您在Jersey中使用Jackson,您可能需要获取该方法返回的值并将其转换为JSON

Response response = getAllEmployees();
Object retval = response.getEntity();
try {
    ObjectMapper mapper = new ObjectMapper();
    // I like this formatting. You can change it.
    mapper.configure(Feature.INDENT_OUTPUT, true);
    mapper.configure(Feature.WRITE_ENUMS_USING_TO_STRING, true);
    mapper.configure(Feature.USE_ANNOTATIONS, false);
    mapper.configure(Feature.FAIL_ON_EMPTY_BEANS, false);
    mapper.setSerializationInclusion(Inclusion.NON_NULL);
    mapper.getSerializationConfig().setSerializationInclusion(JsonSerialize.Inclusion.NON_NULL);
    mapper.getSerializationConfig().withSerializationInclusion(JsonSerialize.Inclusion.NON_NULL);
    String json = mapper.writeValueAsString(retval);
    ... assert something about the string
} catch (JsonProcessingException e) {
    // do something
} catch (IOException e) {
    // do something
}

其中一些是我的猜测和猜测,但可能会有所帮助。您可以尝试在MemoryTestContainerFactory中与
一起使用:

它启动Jersey应用程序并直接调用内部API来处理由测试框架提供的客户端创建的请求。不涉及网络通信。这个容器不支持servlet和其他依赖于容器的特性,但对于简单的单元测试来说,它是一个完美的选择

看起来要使用它,您只需扩展
JerseyTest
,然后重写
getTestContainerFactory()
,然后按照其余说明操作,例如:

public class EmployeeResourceTest extends JerseyTest {
    @Override
    protected Application configure() {
        // set up employee resource with mock dependencies etc...
        return new ResourceConfig().registerInstances(employeeResource);
    }

    @Test
    public void getAllEmployees() {
        final String response = target("getallemployees").request().get(String.class);
        // assert etc...
    }
}
我在
configure()
中使用了
registerInstances
而不是
registerClasses
,因为看起来您可以提供一个现成的
资源
,但是可以使用您可能需要的任何模拟依赖项进行设置-尽管我自己没有尝试过

test类有点不灵活,因为您只能在
configure()
方法中一次性设置依赖项,因此使用-可能值得研究,尽管我不确定它是否能与
JerseyTest
继承一起工作。它可以允许您在每个
@Test
方法中向模拟添加行为,例如:

    @Mock
    private EmployeeResourceDependency dependency;

    @InjectMocks
    private EmployeeResource employeeResource;

    // configure() as above but without mock setup up etc...

    @Test
    public void getAllEmployees() {
        given(dependency.getEmployees()).willReturn(...); 

        // etc...

但就像我说的,可能根本不可能把它们混在一起

你用哪种杰克逊版本来做这个?因为Feature.INDENT_输出无法识别……这实际上是有效的:),唯一的问题是我将整个实体对象作为JSON字符串获取,它看起来是这样的:
{“rawType”:“java.util.ArrayList”,“type”:{“actualTypeArguments”:[“dev.enties.Employee”],“rawType”:“java.util.List”},“entity”:[{“idEmployee”:0,“name”:“theName”,“姓氏”:“theSurname”}
而原始json看起来是这样的:
“employee”:[{“ideemployee”:0,“name”:“theName”,“姓氏”:“theSurname”}
抱歉。您必须首先从响应中删除实体。更改代码示例以执行此操作。我不完全确定这样做是否正确,但类似于此。实际上,我在之前的注释中打印的消息是我从响应中删除实体后得到的消息。它不是json字符串,但几乎相同…它似乎在里面。一定是需要其他东西才能得到最初的结果。