Joobie: Как правильно выполнить модульное тестирование маршрута, который возвращает различное содержимое в зависимости от MediaType?

В настоящее время я экспериментирую с написанием webapps/apis с использованием Jooby. У меня есть настроенная конечная точка, которая возвращает данные учетной записи, либо в виде HTML, либо в виде JSON, в зависимости от значения заголовка accept. Эта конечная точка работает и возвращает правильную информацию.

При написании модульных тестов в JUnit, как передать значение заголовка accept вместе с моим запросом get, чтобы я мог правильно проверить то, что возвращается из запроса?

Я попытался с помощью Mockito смоделировать объект Request и вернуть ответы на различные вызовы объекта request, но я не могу найти в документации, как Jooby проверяет значения заголовка в своем собственном объекте Request при использовании Results.when метод.

Это моя конечная точка:

get("/allAccounts", () ->
   Results
          .when(MediaType.html, () -> Results.html("display").put("accounts", accounts))
          .when(MediaType.json, () -> accounts)
          .when("*", () -> Status.NOT_ACCEPTABLE)
);

Испытания, проведенные до сих пор, были похожи на следующие. Я перепробовал много разностных методов вместо 'type()', таких как.accept(), но ни один из них не был запрошен, так как метод get() MockRouter никогда не возвращает строку ни при одном из этих условий.

@Test
public void allAccountsHTMLunitTest() throws Throwable {

    Request req = mock(Request.class);
    when(req.type()).thenReturn(MediaType.html);

    String result = new MockRouter(new App(), req)
        .get("/allAccounts");

    assertEquals(// some assertion );
}

Я ожидаю (возможно, ошибочно), что когда я делаю запрос get через MockRouter с заголовком "accept: text/html" или "accept: application/json", он должен вернуть строку, содержащую html или json соответственно.

Вместо этого я получаю сообщение об ошибке, что пытаюсь привести объект Result к строке.

Я серьезно не понимаю это?

1 ответ

Решение

Это правильно, и это в основном разница между модульными и интеграционными тестами.

Для юнит-тестов все MockRouter делает, чтобы вызвать функцию обработчика маршрута, функцию /allAccounts возвращает объект Result, поэтому вы получили исключение приведения класса.

Вот ваш пример, но с использованием Result доступ к значению через result.get()

  @Test
  public void allAccountsHTMLunitTest() throws Throwable {

    Request req = mock(Request.class);
    when(req.type()).thenReturn(MediaType.html);

    Result result = new MockRouter(new App(), req)
        .get("/allAccounts");

    View view = result.get();
    assertEquals("display", view.name());
    assertEquals("{accounts=[1, 2]}", view.model().toString());

  }

Надеется, что это помогает.

Другие вопросы по тегам