我使用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();
}
我需要开发一些单元测试(不是集成测试),我想以某种方式模拟调用此方法的HTTPRequest,然后获取json String。最好的选择是使用mockito。
有关于如何做的建议吗?
谢谢!
答案 0 :(得分:1)
问题是该方法将Response
对象返回给调用者,该调用者深入框架代码中。它不返回JSON字符串。
如果您需要在方法内部模拟某些内容,可以使用Mockito。这应该有用。
但是你可能需要获取方法返回的值,并将它转换为JSON,如果你使用Jackson和Jersey。
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
}
答案 1 :(得分:1)
其中一些是猜测工作和我的猜测,但它可能会有所帮助。您可以尝试将Jersey Test Framework与InMemoryTestContainerFactory
:
启动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...
}
}
我在registerInstances
中使用registerClasses
而不是configure()
,因为看起来您可以提供现成的Resource
,但设置了您可能想要的任何模拟依赖项 - 尽管我自己没试过。
测试类有点不灵活,因为你只能在configure()
方法中一次性设置依赖项,因此使用MockitoJUnitRunner
进行调查可能是值得的 - 尽管我不是确定它是否适用于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...
但就像我说的那样根本不可能混合它们。