2013-10-01 2 views
2

통합 JUnit 테스트를 작성하고 있습니다. 내 임무는 내 로컬 서버의 응답이 정확한지 테스트하는 것입니다. 언급 된 서버는 분석 할 페이지의 주소를 GET 매개 변수로 취합니다 (예 : localhost:8000/test?url=http://www.example.com).테스트 목적으로 새로 생성 된 부두 서버에 요청을 보냅니다.

www.example.com에 의존하지 않으려 고 항상 동일한 컨텐츠를 제공하는 내 고유의 부두 (jetty) 서버에 대해이 특정 테스트를 시작하겠습니다.

private static class MockPageHandler extends AbstractHandler { 
    public void handle(String target,Request baseRequest, HttpServletRequest request, 
      HttpServletResponse response) 
      throws IOException, ServletException { 
     response.setContentType("text/html; charset=utf-8"); 
     response.setStatus(HttpServletResponse.SC_OK); 
     final String responseString = loadResource("index.html"); 
     response.getWriter().write(responseString); 
     baseRequest.setHandled(true); 

    } 
} 

public void test() throws Exception { 
    final int PORT = 8080; 
    final Server server = new Server(PORT); 
    server.setHandler(new MockPageHandler()); 
    server.start(); 

    final ContentResponse response = 
     client.newRequest("http://localhost:8000/test?url=http://localhost:8080").send(); 

    /* some assertions. */ 

    server.stop(); 
    server.join(); 
} 

나는이 테스트를 실행할 때마다, MockPageHandlerhandle 방법은 호출되지 않습니다. 이것이 작동하지 않는 이유가 있습니까?

P. server.stop()을 제거하고 브라우저 유형이 http://localhost:8080이면 적절한 페이지가 표시됩니다.

답변

5

빠른 대답 :

server.join() 라인을 제거합니다. 이 줄은 서버 스레드가 멈출 때까지 junit 스레드를 대기 상태로 만듭니다. 단위 테스트에는 필요하지 않습니다.

긴 대답은 :

우리 (부두 개발자)의 JUnit과 부두 임베디드 서버를 사용하는 방법에 대해 무엇을 배웠는가.

테스트 방법이 1 개인 경우 또는 서버가 테스트 방법간에 원본이어야한다는 요구 사항이있는 경우 @Before@After 주석을 사용하여 서버를 시작하고 중지하십시오.

예 @Before/@After (부두 9.x의) :이 기술은 빈을 선택하는 기본 스택을 알려주는 매직 넘버는 포트 0에 서버 시작을하게

public class MyTest 
{ 
    private Server server; 
    private URI serverUri; 

    @Before 
    public void startServer() throws Exception 
    { 
     this.server = new Server(); 
     ServerConnector connector = new ServerConnector(server); 
     connector.setPort(0); // let connector pick an unused port # 
     server.addConnector(connector); 

     ServletContextHandler context = new ServletContextHandler(); 
     context.setContextPath("/"); 
     server.setHandler(context); 

     // Serve capture servlet 
     context.addServlet(new ServletHolder(new MyServlet()),"/my/*"); 

     // Start Server 
     server.start(); 

     String host = connector.getHost(); 
     if (host == null) 
     { 
      host = "localhost"; 
     } 
     int port = connector.getLocalPort(); 
     this.serverUri = new URI(String.format("http://%s:%d/",host,port)); 
    } 

    @After 
    public void stopServer() 
    { 
     try 
     { 
      server.stop(); 
     } 
     catch (Exception e) 
     { 
      e.printStackTrace(System.err); 
     } 
    } 

    @Test 
    public void testMe() 
    { 
     // Issue request to server 
     URI requestUri = serverUri.resolve("/my/test"); 
     // assert the response 
    } 
} 

포트를 클릭하고 청취를 시작하십시오. 그런 다음 테스트 케이스는 서버에 수신 대기중인 포트 번호를 묻고이 테스트 실행에 적합하도록 serverUri 필드를 빌드합니다.

이 방법은 효과적이지만 각 방법에 대해 서버를 시작/중지합니다.

@BeforeClass@AfterClass 주석을 사용하여 전체 테스트 클래스에 대해 한 번 서버를 시작/중지하고이 시작된 서버에 대해 테스트 클래스 내부의 모든 메소드를 실행하십시오.

예 @BeforeClass/@AfterClass (부두 9.x의) :

public class MyTest 
{ 
    private static Server server; 
    private static URI serverUri; 

    @BeforeClass 
    public static void startServer() throws Exception 
    { 
     server = new Server(); 
     ServerConnector connector = new ServerConnector(server); 
     connector.setPort(0); // let connector pick an unused port # 
     server.addConnector(connector); 

     ServletContextHandler context = new ServletContextHandler(); 
     context.setContextPath("/"); 
     server.setHandler(context); 

     // Serve capture servlet 
     context.addServlet(new ServletHolder(new MyServlet()),"/my/*"); 

     // Start Server 
     server.start(); 

     String host = connector.getHost(); 
     if (host == null) 
     { 
      host = "localhost"; 
     } 
     int port = connector.getLocalPort(); 
     serverUri = new URI(String.format("http://%s:%d/",host,port)); 
    } 

    @AfterClass 
    public static void stopServer() 
    { 
     try 
     { 
      server.stop(); 
     } 
     catch (Exception e) 
     { 
      e.printStackTrace(System.err); 
     } 
    } 

    @Test 
    public void testMe() 
    { 
     // Issue request to server 
     URI requestUri = serverUri.resolve("/my/test"); 
     // assert the response 
    } 
} 

많이 다를하지 않습니다? 예, 변경 사항은 미묘합니다. @Before@BeforeClass, @After@AfterClass이되었다. 시작/중지 메소드는 이제 정적입니다. serverserverUri 필드는 이제 정적입니다.

이 기술은 동일한 서버에 액세스하는 수십 개의 테스트 메소드가 있고 그 요청이 서버의 상태를 변경하지 않는 경우에 사용됩니다. 이렇게하면 각 테스트 메소드간에 서버를 재 작성하지 않아도 테스트 케이스 실행 속도가 향상됩니다.

+0

당신이 제안한대로 server.join()을 제거하면 마술처럼 작동합니다! – amazia

0

http 테스트를 위해 "com.jayway.restassured"를 시도하십시오. 너무 쉬운 몇 가지 테스트 쓰기 :

@Test 
public void testNotGetAll() { 
    expect(). 
     statusCode(404). 
    when(). 
     get(baseUrl+"/games/"); 
} 

이 메서드 호출 "http://mywebserver.local:8080/rest/games/"및 404 HTTP 상태 코드가 반환되어 있는지 확인합니다.

이 접근법은 예를 들어 Maven 라이프 사이클의 사전 통합 테스트에서 시작된 Jetty 서버와 동기화되어 완벽한 통합을 프로세스 통합 테스트와 일치시킵니다!