2013-06-30 1 views
1

Google App Engine 프로젝트의 단위 테스트를 만들려고합니다. 유스 케이스는 다음과 같습니다. 클라이언트가 API에 업로드 URL을 쿼리하면 BLOB 저장소에 데이터를 저장해야하므로 클라이언트는 URL이있는 JSON 인 코드 구조를 수신합니다. 그런 다음 클라이언트는 해당 URL에 데이터를 업로드합니다.Google App Engine 서비스 (예 : Blobstore)의 답변 모의 방법

서블릿의 구현은 매우 간단하다 :

@Override 
protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
     throws ServletException, IOException { 
    Gson gson = new Gson(); 
    Map<String, String> result = new HashMap<String, String>(); 
    result.put("uploadurl", BlobstoreServiceFactory.getBlobstoreService() 
      .createUploadUrl("/api/v1/import")); 
    gson.toJson(result, resp.getWriter()); 
} 

좋은 방식으로 클라이언트가 실제로 올바른 데이터를 수신 않습니다 여부를 확인하기 위해 테스트가 있어야한다. 따라서 카운터 JUnit 테스트가 있어야합니다. 테스트 결과를 확인할 수있는 고정 업로드 URL을 반환하도록 BLOB 저장소 서비스를 조롱하고 싶었습니다.

그러나 Blobstore 서비스를 무력화하는 방법을 알지 못합니다. Mockito를 사용하여 정적 getBlobstoreService()를 조롱 할 수는 없지만 LocalBlobstoreServiceTestConfig를 사용하여 createUploadUrl()에 대한 대답을 어떻게 무시할 수 있는지 알 수 없습니다. (https://code.google.com/p/powermock/) 정적 클래스/메소드를 비웃음

public class ImportServletTest { 
    public static class Response { 
    String uploadurl; 

    void setUploadurl(String url) { 
     this.uploadurl = url; 
    } 
} 

private LocalBlobstoreServiceTestConfig blobstoreConfig = new LocalBlobstoreServiceTestConfig(); 

private LocalServiceTestHelper helper = new LocalServiceTestHelper(blobstoreConfig); 
@Test 
public void getsUploadURL() throws IOException, ServletException { 
    ImportServlet servlet = new ImportServlet(); 

    HttpServletResponse response = mock(HttpServletResponse.class); 
    try (CharArrayWriter output = new CharArrayWriter(); 
      PrintWriter writer = new PrintWriter(output);) { 
     when(response.getWriter()).thenReturn(writer); 

     servlet.doGet(null, response); 
     writer.flush(); 

     Response apiResponse = new Gson().fromJson(output.toString(), Response.class); 
     assertEquals("http://mysite/_ah/theurl", apiResponse.uploadurl); 
    } 
} 

@Before 
public void setupGae() throws IOException { 
    helper.setUp(); 
} 

@After 
public void teardownGae() { 
    helper.tearDown(); 
} 
} 
+0

blob 저장소 서비스를 매개 변수로 서블릿의 생성자에 전달할 수 없습니까? – fge

+1

서블릿은 서블릿 프레임 워크에 의해 인스턴스화되며 인수가없는 생성자가 필요합니다. 물론 여러 생성자를 제공하여 실제 생성자 서비스를 다른 생성자로 전달할 수도 있지만 이렇게하면 코드가 필요 이상으로 복잡해집니다. 또한 서블릿 생성자의 서비스에 액세스 할 수 있는지 여부는 확실하지 않습니다. –

답변

1

이 (http://googletesting.blogspot.it/2008/12/static-methods-are-death-to-testability.html) 매우 위험 일반적이지만, 유사한 경우에 나는 PowerMock를 사용하여 일부 성공을 거두었 :

테스트를 작성하는 나의 시도는 다음과 같이이었다 내 통제하에 있지 않은 정적 클래스의 동작을 재정의 할 수 있습니다. 난 당신이 전체 방법 체인을 조롱 할 것 같아요

BlobstoreServiceFactory.getBlobstoreService().createUploadUrl() 

대신 Blob 저장소에 의해 생성 된 그의 사용자 지정 URL을 반환 할 수 있습니다.

+0

감사합니다. 나는 그것을 조사 할 것입니다. 그처럼 간단한 방법을 테스트하기 위해 테스트 코드가 크기와 복잡성이 폭발적이라는 사실에 수치스러워합니다. –