【问题标题】:What is the point of writing behavioral JUnit test in Spring-Rest?在 Spring-Rest 中编写行为 JUnit 测试有什么意义?
【发布时间】:2017-10-11 12:21:50
【问题描述】:

我是 JUnit mockito 的新手,我为我的 Spring 休息资源编写了这个测试函数。

@Test
public void getAllMessageHappyTest() throws Exception {
    List<Message> messageList = new ArrayList<>();
    messageList.add(new Message(1,"Hello"));
    messageList.add(new Message(5,"Hello world"));
    messageList.add(new Message(3,"Hello World, G!"));

    when(messageService.getAllMessages()).thenReturn(messageList);
    RequestBuilder requestBuilder = MockMvcRequestBuilders.get("/messages/").accept(MediaType.APPLICATION_JSON);
    MvcResult mvcResult = mockMvc.perform(requestBuilder).andReturn();

   String expected = ""; // expected
   JSONAssert.assertEquals(expected,mvcResult.toString(),false);
}

在上述场景中,when(messageService.getAllMessages()).thenReturn(messageList); 返回由我(或团队成员)编写的messageList,我将返回的 JSON 与 @ 进行比较987654325@ 也将由我(或同一团队成员)编写。所以这两件事都是由同一个人写的,所以进行这种测试有什么意义。

【问题讨论】:

  • 测试中硬编码的行为是针对某些服务的,这会测试控制器层。

标签: java spring unit-testing junit mockito


【解决方案1】:

如果我正确理解了这个问题,那么问题就是这样;因为编写测试的人也会硬编码(以 JSON 字符串的形式)测试可能是多余的,或者至少可能价值有限。也许您的问题的子文本是,既然编写底层端点的人将提供期望,那么它必须通过,如果它的成功是预先注定的,那么它就没有什么价值了。

但是,无论谁编写测试以及谁编写被测代码,您上面展示的示例测试都是有价值的,因为:

  • 它测试的不仅仅是重新调整的 JSON,它还测试...
    • REST 端点映射是正确的,即它公开了一个名为 "/messages/" 并接受 JSON 的端点
    • REST 层使用了一个序列化器,它产生一些 JSON
  • 继续运行此测试用例将确保即使在您(或您团队的其他成员)不再处理此代码之后,此端点的预期行为也能继续得到满足,或者换句话说;它充当回归安全网。
  • 将来可能会更改被测代码,如果是这样,那么此测试用例提供了一个基准,可以根据该基准进行未来的开发。
  • 测试用例为您的代码提供了一种文档形式;不熟悉此代码库的人可以查看测试以了解代码的预期行为方式。

此外,此测试用例可以扩展为包括对无效路径的测试,例如无效响应、不安全的访问尝试等,从而提高测试覆盖率。

更新 1:回应此评论:

即使有人在实际代码中进行了更改,现在在制作实际代码后生成了不同类型的 JSON(说不是按要求),即使这样,测试用例也将通过,因为那时是硬编码的,并且预期也是硬编码的。那么有什么意义呢?

这样的测试显然没有意义:

String json = "...";

when(foo.getJson()).thenReturn(json);

assertEquals(json, foo.getJson());

那是不是您的测试所做的。相反,您的测试断言响应 - 以 JSON 的形式 - 与您的模拟 messageService.getAllMessages() 返回的响应的序列化形式相匹配。因此,您的测试涵盖了序列化部分以及 Spring MVC 层的各个方面,例如端点->控制器映射以及拦截器和过滤器(如果有的话)。

【讨论】:

  • 即使有人在实际代码中进行了更改,现在在实际代码生成后生成了不同类型的 JSON(说不是按要求)即使那样测试用例也会通过,因为 when then is hardcoded 和 @987654325 @ 也是硬编码的。那么有什么意义呢?
猜你喜欢
  • 2016-01-06
  • 2012-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-14
  • 1970-01-01
  • 2021-07-26
  • 2019-06-21
相关资源
最近更新 更多