我实现了 REST Web服务,并希望使用jUnit测试来测试我的实现。
当我使用 REST 参考框架 Jersey 时,我想使用提供的测试框架 JerseyTest ,但我得到一些奇怪的行为:
如果我的资源创建了一个包含String的响应,那么每件事都可以正常工作(参见测试用例 responseCodeIs404IfGetForNotExistingGuiTag())。 一旦我的响应包含pojo,就会出现问题(请参阅测试用例 responseCodeIs200IfGetForExistingGuiTag())。我没有收到预期的200响应代码,而是500'内部服务器错误'。如果我“手动”测试整个界面,那么每件事都可以。所以我假设我需要以某种方式配置测试框架,但我无法弄清楚如何。
我将this实施作为模板。
我使用Jersey 2.0(因为它目前在我的glassfish 4.0上运行(没有机会更新)),Mockito作为模拟框架,Jackson作为JSON框架。
我希望你们能帮助我。如果您需要更多信息,请告诉我。
GuiTagResource.java
@Path("/char")
public class GuiTagResource {
private GuiTagRepository guiTagRepo;
@Inject
public void setGuiTagRepo(GuiTagRepository guiTagRepo) {
this.guiTagRepo = guiTagRepo;
}
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("{id}")
public Response getGuiTagById(@PathParam("id") int guiTagNo) {
Optional<GuiTag> guiTag = guiTagRepo.getCharGuiTagById(guiTagNo);
Response response;
if (!guiTag.isPresent()) {
//This case works fine
response = Response.status(404).entity("GuiTag with id " + Integer.toString(guiTagNo) + " was not found.")
.type(MediaType.APPLICATION_JSON).build();
} else {
//This case produces a 404 Error
CharacteristicGuiTag guiTagTo = fromEntity((CharacteristicGuiTagEntity) guiTag.get());
response = Response.status(200).entity(guiTagTo).build();
}
return response;
}
}
GuiTagResourceTest.java
public class GuiTagResourceTest extends JerseyTest {
@Mock
private GuiTagRepository repoMock;
@Override
protected Application configure() {
MockitoAnnotations.initMocks(this);
enable(TestProperties.LOG_TRAFFIC);
enable(TestProperties.DUMP_ENTITY);
ResourceConfig config = new ResourceConfig(GuiTagResource.class);
config.register(new InjectableProvider());
return config;
}
@Test
public void responseCodeIs404IfGetForNotExistingGuiTag() {
when(repoMock.getCharGuiTagById(Mockito.anyInt())).thenReturn(absent());
Response response = target("char/5").request().get();
//Passes -> response code is 404
assertThat(response.getStatus(), is(404));
}
@Test
public void responseCodeIs200IfGetForExistingGuiTag() {
Optional<GuiTag> compareTag = getGuiTagMock();
CharacteristicGuiTag pojo = fromEntity((CharacteristicGuiTagEntity) compareTag.get());
when(repoMock.getCharGuiTagById(Mockito.anyInt())).thenReturn(compareTag);
Response response = target("char/5").request().get();
CharacteristicGuiTag responsePojo = response.readEntity(CharacteristicGuiTag.class);
//Doesn't pass as response is 500?
assertThat(response.getStatus(), is(200));
}
private Optional<GuiTag> getAbsentMock() {
//returns a Optional.absent() to fake a failed db get.
}
private Optional<CharacteristicGuiTagEntity> getCharGuiTagMock() {
//returns a guiTag
}
class InjectableProvider extends AbstractBinder implements Factory<GuiTagRepository> {
@Override
protected void configure() {
bindFactory(this).to(GuiTagRepository.class).in(Singleton.class);
}
public GuiTagRepository provide() {
return repoMock;
}
public void dispose(GuiTagRepository service) {
repoMock = null;
}
}
}
控制台日志
Nov 21, 2014 12:53:26 PM org.glassfish.jersey.server.ApplicationHandler initialize
INFO: Initiating Jersey application, version Jersey: 2.0 2013-05-03 14:50:15...
Nov 21, 2014 12:53:27 PM org.glassfish.jersey.test.grizzly.GrizzlyTestContainerFactory$GrizzlyTestContainer start
INFO: Starting GrizzlyTestContainer...
Nov 21, 2014 12:53:27 PM org.glassfish.grizzly.http.server.NetworkListener start
INFO: Started listener bound to [localhost:9998]
Nov 21, 2014 12:53:27 PM org.glassfish.grizzly.http.server.HttpServer start
INFO: [HttpServer] Started.
Nov 21, 2014 12:53:28 PM org.glassfish.jersey.filter.LoggingFilter log
INFO: 1 * LoggingFilter - Request received on thread main
1 > GET http://localhost:9998/char/5
Nov 21, 2014 12:53:28 PM org.hibernate.validator.internal.util.Version <clinit>
INFO: HV000001: Hibernate Validator 5.0.0.Final
Nov 21, 2014 12:53:28 PM org.glassfish.jersey.filter.LoggingFilter log
INFO: 2 * LoggingFilter - Response received on thread main
2 < 500
2 < Date: Fri, 21 Nov 2014 11:53:28 GMT
2 < Content-Length: 0
2 < Connection: close