Jersey 中使用 Jersey Test Framework 做測試時
如果遇到需要使用 Servlet 的狀況,例如使用了 @Context HttpServletRequest request
可能就會注意到,HttpServletRequest 這類應該要自動被注入的東西,在測試時都沒有被注入
因此會發生像是 NullPointerException 等等的錯誤。
雖然有不少網友有去 Jersey 社群詢問或直接開 bug
但官方開發人員的回應是表示這並沒有違背設計,因此也沒有打算要修復。
至於沒有違背設計的原因,可以參考 [6],實際上預設 JerseyTest 會打開的伺服器,僅包含 HTTP container
因此對於 Servlet 注入所需要的 Servlet container 沒有任何反應。
如果想要使用 Servlet 的話,依照官方文件 [6] 的描述,應該改用 GrizzlyWebTestContainerFactory 去提供 test container。
要使用 GrizzlyWebTestContainerFactory,首先當然是 Maven 的設定必須使用 Grizzly
因此必須加上這樣的 dependancy:
<dependencyManagement> <dependencies> <dependency> <groupId>org.glassfish.jersey</groupId> <artifactId>jersey-bom</artifactId> <version>${jersey.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <properties> <jersey.version>2.23</jersey.version> </properties> </dependencies> <dependency> <groupId>org.glassfish.jersey.test-framework.providers</groupId> <artifactId>jersey-test-framework-provider-grizzly2</artifactId> <scope>test</scope> </dependency> </dependencies>
在上述的 pom.xml 中,指定了會使用 Grizzly2 來提供 test container 服務,並且使用的版本是 2.23。
除了 Maven 以外,在程式碼的部份也需要做一些額外的設定,以要求使用具有 Servlet 功能的 container。
public class MyTest extends JerseyTest { @Override protected TestContainerFactory getTestContainerFactory() { return new GrizzlyWebTestContainerFactory(); } @Override protected DeploymentContext configureDeployment() { ResourceConfig config = new ResourceConfig(MyRestfulApi.class); return ServletDeploymentContext .forServlet(new ServletContainer(config)) .build(); } @Test public void testServlet () { Response response = target("/") .queryParam("a", 1) .queryParam("b", "test") .request() .get(Response.class); Assert.assertEquals(200, response.getStatus()); } } @Path("/") @Produces public class MyRestfulApi { @GET public Response test (@Context HttpServletRequest request) { System.out.println("Request URL: " + request.getRequestURL().toString()); System.out.println("Queries: " + request.getQueryString()); return Response.ok().build(); } }
在上述的程式碼中,有兩個類別,MyRestfulApi 是撰寫的 Restful API,而 MyTest 則是測試的程式。
在 RESTful API 中,做的事情只是單純把 Request 的網址和參數印出來而已。
而測試程式 MyTest,則是透過 Override 覆寫了兩個 method
用來指定要使用具有 Servlet 功能的 container,並且 context 也要以 Servlet 的形式佈署
這樣才能順利地讓 Servlet 功能正常運作。
接著在測試案例 testServlet() 中,就產生一個會送出兩個 query parameters 的 HTTP request 給 MyRestfulApi
並且檢查回應的 HTTP status code 是否為 200。
真正執行上述的測試程式時,console 會印出下列的結果,表示 Servlet 確實正常在運作。
Request URL: http://localhost:9998/ Queries: a=1&b=test
相關資源
上篇:對 Jersey 製作的 RESTful API 做單元測試(一)
參考資料
- jersey2 Unit testing,HttpServletRequest is null
- Problems running JerseyTest when dealing with HttpServletResponse
- Injection of HttpServletRequest when using JerseyTest does not work
- HttpServletRequest always null on test case
- JerseyTest using GrizzlyWebTestContainerFactory in Jersey 2.13
- 26.2. Supported Containers
沒有留言:
張貼留言