2016-05-14 5 views
2

TomcatにデプロイされたJersey Webアプリケーションを構築しています。私はアプリを単体テストする方法を理解するのに苦労している。TomcatにデプロイされたJersey Webアプリケーションを単体テストできますか?

私のテストでクラスをインスタンス化し、それらのメソッドを呼び出すだけで、コアビジネスロジック(非ジャージーリソースクラス)をテストすることができます(JerseyやTomcatとは関係ありません)。

しかし、Jerseyのリソースクラス(URLにマップされるクラス)を単体テストする正しい方法は何ですか?

このためにTomcatを実行する必要がありますか?あるいは、リクエストとレスポンスのオブジェクトを模擬し、テストでリソースクラスをインスタンス化し、モックをクラスにフィードする必要がありますか?

私はJerseyのサイトでテストについて読んだことがありますが、彼らの例ではGrizzlyではなくTomcatを使用しています。

どうすればよいか説明してください。サンプルコードは大歓迎です。

+1

を持つことができます。それは統合テストです。その区別は重要です。 – duffymo

+0

私はそれを書こうとしていたが、正確な点はすでに@duffymoによって作られていた。ユニットテストではなく、統合テストを求めています。 – Siddharth

答えて

2

ユニットテストを行う場合は、サーバーを起動する必要はありません。あなたはサービス(ビジネス層)またはUriInfoのような他の注射とその性質のものを持っているならば、あなたはただそれを嘲笑することができます。かなり一般的な模擬フレームワークはMockitoです。


あなたは統合テストを実行したい場合は、個人的に私は表示されません。以下は

import javax.inject.Inject; 
import javax.ws.rs.GET; 
import javax.ws.rs.Path; 
import javax.ws.rs.PathParam; 
import javax.ws.rs.core.Response; 

import org.junit.Before; 
import org.junit.Test; 
import org.mockito.Mockito; 

import static org.hamcrest.CoreMatchers.instanceOf; 
import static org.hamcrest.CoreMatchers.is; 
import static org.junit.Assert.assertThat; 

/** 
* Beside Jersey dependencies, you will need Mockito. 
* 
* <dependency> 
*  <groupId>org.mockito</groupId> 
*  <artifactId>mockito-core</artifactId> 
*  <version>1.10.19</version> 
* </dependency> 
* 
* @author Paul Samsotha 
*/ 
public class SomethingResourceUnitTest { 

    public static interface SomeService { 
     String getSomethingById(int id); 
    } 

    @Path("something") 
    public static class SomethingResource { 

     private final SomeService service; 

     @Inject 
     public SomethingResource(SomeService service) { 
      this.service = service; 
     } 

     @GET 
     @Path("{id}") 
     public Response getSomethingById(@PathParam("id") int id) { 
      String result = service.getSomethingById(id); 
      return Response.ok(result).build(); 
     } 
    } 

    private SomethingResource resource; 
    private SomeService service; 

    @Before 
    public void setUp() { 
     service = Mockito.mock(SomeService.class); 
     resource = new SomethingResource(service); 
    } 

    @Test 
    public void testGetSomethingById() { 
     Mockito.when(service.getSomethingById(Mockito.anyInt())).thenReturn("Something"); 

     Response response = resource.getSomethingById(1); 
     assertThat(response.getStatus(), is(200)); 
     assertThat(response.getEntity(), instanceOf(String.class)); 
     assertThat((String)response.getEntity(), is("Something")); 
    } 
} 

完全な例関連項目ですあなたがGrizzlyコンテナを走らせているかどうか、Tを走らせるかどうかアプリケーションでTomcat固有のものを使用していない限り、omcatコンテナを使用します。

Jersey Test Frameworkを使用すると統合テストに適していますが、Tomcatプロバイダはありません。グリズリー、インメモリ、桟橋があります。 HttpServletRequestServletContextなどのサーブレットAPIを使用していない場合は、インメモリプロバイダが実行可能なソリューションになる可能性があります。より迅速なテスト時間を提供します。

関連項目:


あなたは Tomcatを使用しなければならない場合は、独自の組み込みTomcatを実行することができます。私は多くの文書を見つけられませんでしたが、example in DZoneがあります。私は実際に埋め込まれたTomcatを使用していませんが、前のリンクに例を行く、あなたはユニットテストではありません(仕事にテストされています)、次のようなもの

import java.io.File; 

import javax.inject.Inject; 
import javax.ws.rs.GET; 
import javax.ws.rs.Path; 
import javax.ws.rs.PathParam; 
import javax.ws.rs.client.ClientBuilder; 
import javax.ws.rs.core.Response; 

import org.apache.catalina.Context; 
import org.apache.catalina.startup.Tomcat; 
import org.glassfish.hk2.utilities.binding.AbstractBinder; 
import org.glassfish.jersey.server.ResourceConfig; 
import org.glassfish.jersey.servlet.ServletContainer; 
import org.junit.After; 
import org.junit.Before; 
import org.junit.Test; 

import static org.hamcrest.CoreMatchers.is; 
import static org.junit.Assert.assertThat; 

/** 
* Aside from the Jersey dependencies, you will need the following 
* Tomcat dependencies. 
* 
* <dependency> 
*  <groupId>org.apache.tomcat.embed</groupId> 
*  <artifactId>tomcat-embed-core</artifactId> 
*  <version>8.5.0</version> 
*  <scope>test</scope> 
* </dependency> 
* <dependency> 
*  <groupId>org.apache.tomcat.embed</groupId> 
*  <artifactId>tomcat-embed-logging-juli</artifactId> 
*  <version>8.5.0</version> 
*  <scope>test</scope> 
* </dependency> 
* 
* See also https://dzone.com/articles/embedded-tomcat-minimal 
*  
* @author Paul Samsotha 
*/ 
public class SomethingResourceTomcatIntegrationTest { 

    public static interface SomeService { 
     String getSomethingById(int id); 
    } 

    public static class SomeServiceImpl implements SomeService { 
     @Override 
     public String getSomethingById(int id) { 
      return "Something"; 
     } 
    } 

    @Path("something") 
    public static class SomethingResource { 

     private final SomeService service; 

     @Inject 
     public SomethingResource(SomeService service) { 
      this.service = service; 
     } 

     @GET 
     @Path("{id}") 
     public Response getSomethingById(@PathParam("id") int id) { 
      String result = service.getSomethingById(id); 
      return Response.ok(result).build(); 
     } 
    } 

    private Tomcat tomcat; 

    @Before 
    public void setUp() throws Exception { 
     tomcat = new Tomcat(); 
     tomcat.setPort(8080); 

     final Context ctx = tomcat.addContext("/", new File(".").getAbsolutePath()); 

     final ResourceConfig config = new ResourceConfig(SomethingResource.class) 
       .register(new AbstractBinder() { 
        @Override 
        protected void configure() { 
         bind(SomeServiceImpl.class).to(SomeService.class); 
        } 
       }); 
     Tomcat.addServlet(ctx, "jersey-test", new ServletContainer(config)); 
     ctx.addServletMapping("/*", "jersey-test"); 

     tomcat.start(); 
    } 

    @After 
    public void tearDown() throws Exception { 
     tomcat.stop(); 
    } 

    @Test 
    public void testGetSomethingById() { 
     final String baseUri = "http://localhost:8080"; 
     final Response response = ClientBuilder.newClient() 
       .target(baseUri).path("something").path("1") 
       .request().get(); 
     assertThat(response.getStatus(), is(200)); 
     assertThat(response.readEntity(String.class), is("Something")); 
    } 
} 
関連する問題