首页 > 解决方案 > Joobie:如何正确地对根据 MediaType 返回不同内容的路由进行单元测试?

问题描述

我目前正在尝试使用 Jooby 编写 webapps/apis。我设置了一个端点,该端点根据接受标头值返回帐户数据,可以是 HTML 也可以是 JSON。此端点工作并返回正确的信息。

在 JUnit 中编写单元测试时,如何将接受标头值与我的 get 请求一起传递,以便我可以正确测试从请求中返回的内容?

我曾尝试使用 Mockito 来模拟 Request 对象并返回对请求对象的各种调用的响应,但我似乎无法在文档中找到当您使用 Results.when 时,Jooby 如何测试它自己的 Request 对象中的标头值方法。

这是我的端点:

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

到目前为止尝试的测试都类似于以下内容。我尝试了许多不同的方法来代替“type()”,例如 .accept(),但似乎没有一个被查询,因为 MockRouter 的 get() 方法在任何这些条件下都不会返回字符串

@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 );
}

我期望(可能是错误的)当我通过 MockRouter 发出带有标头“accept:text/html”或“accept:application/json”的 get 请求时,它应该分别返回一个包含 html 或 json 的字符串。

相反,我收到一个错误,我试图将 Result 对象转换为字符串。

我是否严重误解了这一点?

标签: javaunit-testingjunitmockitojooby

解决方案


这是正确的,它基本上是单元测试和集成测试之间的区别。

对于单元测试,所有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());

  }

希望这会有所帮助。


推荐阅读