2013-06-30 4 views
1

Я пытаюсь создать единичный тест для моего проекта Google App Engine. Вариант использования следующий: клиент запрашивает API для URL-адреса для загрузки, так как данные должны храниться в блочном хранилище, клиент получает кодированную структуру JSON с URL-адресом. Затем клиент загружает данные на этот 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 test. Я надеялся высмеять службу хранилища blob, чтобы она вернула фиксированный URL-адрес загрузки, который затем может проверить.

Однако я не знаю, как отменить службу blobstore. Использование Mockito Я не могу издеваться над статическим getBlobstoreService(), используя LocalBlobstoreServiceTestConfig. Я понятия не имею, как я могу отменить ответ на createUploadUrl().

Моя попытка написать тест было что-то вроде этого:

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

Сервлеты будут создаваться с помощью структуры сервлета и требуют конструктора no-arg. Я мог бы, конечно, поставлять несколько конструкторов, передавая реальные службы gae в другой конструктор, но это делает код более сложным, чем нужно. Кроме того, я не уверен, разрешен ли доступ к службам в конструкторе сервлета. –

ответ

1

Дразнящий статические классы/методы в целом очень опасно (http://googletesting.blogspot.it/2008/12/static-methods-are-death-to-testability.html), но в подобном случае я имел некоторый успех, используя PowerMock (https://code.google.com/p/powermock/) чтобы переопределить поведение статических классов, которые не были под моим контролем. Я думаю, вы должны будете издеваться весь метод цепи:

BlobstoreServiceFactory.getBlobstoreService().createUploadUrl() 

вернуть пользовательский URL вместо того, что генерируется Blobstore.

+0

Спасибо, я проверю это. Стыдно, что для тестирования такого простого метода мой тестовый код взрывается по размеру и сложности. –

Смежные вопросы