jersey测试如果依赖外部web容器,测试起来就不方便了;如果用maven管理项目的话,编译、打包也很不方便。
无意中发现了jersey-test-framework-grizzly2这么一个测试框架,感觉用起来还可以。根据jersey的使用情况,JerseyTest的应用稍有不同。
都是继承com.sun.jersey.test.framework.JerseyTest类,复写setUp()、configure(),setUp启动内置容器,configure配置资源类包路径,以及必要的servletClass(默认是com.sun.jersey.spi.container.servlet.ServletContainer)。
测试框架maven依赖
<dependency> <groupId>com.sun.jersey.jersey-test-framework</groupId> <artifactId>jersey-test-framework-grizzly2</artifactId> <version>1.19</version> <scope>test</scope> </dependency>
1、单纯使用jersey,没有和其他框架集成,比如spring什么的。这种情况的测试最为简单。项目源码jersey
package com.jersey.demo.resources; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import javax.ws.rs.core.MediaType; import org.junit.Before; import org.junit.Test; import com.jersey.demo.core.entity.Member; import com.sun.jersey.api.client.ClientHandlerException; import com.sun.jersey.api.client.UniformInterfaceException; import com.sun.jersey.api.client.WebResource; import com.sun.jersey.test.framework.AppDescriptor; import com.sun.jersey.test.framework.JerseyTest; import com.sun.jersey.test.framework.WebAppDescriptor; /** * 继承JerseyTest进行测试。 * * @author sean * */ public class MemberResourceTest extends JerseyTest { private final String name = "张三"; private WebResource wr; @Before public void setUp() throws Exception { super.setUp(); wr = resource(); } /** * 默认servletClass=com.sun.jersey.spi.container.servlet.ServletContainer */ @Override protected AppDescriptor configure() { return new WebAppDescriptor.Builder("com.jersey.demo.resources") .contextPath("jerseyDemo").build(); } @Test public void testXml() { Member member = wr.path("member/xml").accept(MediaType.APPLICATION_XML) .get(Member.class); // 验证 assertEquals(name, member.getName()); } // 其他测试用列 }
以上测试类configure()方法中的Builder的部分源码如下,可以看出默认servletClass=ServletContainer,和jersey在web.xml中的配置是一致的。
public class WebAppDescriptor extends AppDescriptor { public static class Builder extends AppDescriptorBuilder<Builder, WebAppDescriptor> { protected Map<String, String> initParams; protected Map<String, String> contextParams; protected Class<? extends HttpServlet> servletClass = ServletContainer.class; } }
2、当jersey和spring集成的时候,需要用到com.sun.jersey.spi.spring.container.servlet.SpringServlet,SpringServlet需要加载spring的配置。如果只是简单的指定SpringServlet.class,将无法注入spring容器中实例对象。
项目源码jerseySpring
// 这样是不行的 FIXME @Override protected AppDescriptor configure() { return new WebAppDescriptor.Builder("com.jersey.demo.resources") .servletClass(SpringServlet.class).contextPath("jerseyDemo") .build(); }
所以自定义了一个servlet,复写了SpringServlet的getDefaultContext()方法,加载spring的配置,这样就完美的集成了。
package com.jersey.demo.web.servlet; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.sun.jersey.spi.spring.container.servlet.SpringServlet; public class MyJerseyServlet extends SpringServlet { private static final long serialVersionUID = 1L; @Override protected ConfigurableApplicationContext getDefaultContext() { return new ClassPathXmlApplicationContext("applicationContext.xml"); } }
package com.jersey.demo.resources; /** * 继承JerseyTest测试。 * * @author sean * */ public class MemberResourceTest extends JerseyTest { private final String name = "张三"; private WebResource wr; @Before public void setUp() throws Exception { super.setUp(); wr = resource(); } /** * 加载自定义的MyJerseyServlet,实现与spring容器的集成。 */ @Override protected AppDescriptor configure() { return new WebAppDescriptor.Builder("com.jersey.demo.resources") .servletClass(MyJerseyServlet.class).contextPath("jerseyDemo") .build(); } @Test public void testXml() { Member member = wr.path("member/xml").accept(MediaType.APPLICATION_XML) .get(Member.class); // 验证 assertEquals(name, member.getName()); } // 其他测试用例 }