在SpringRest中编写行为JUnit测试有什么意义



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

@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与我(或同一团队成员)也将撰写的String expected进行比较。所以这两件事都是由同一个人写的,那么进行这样的测试有什么意义呢。

如果我正确理解了这个问题,问题是这样的;因为编写测试的人也会硬编码(以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层的各个方面,如端点->控制器映射、拦截器和过滤器(如果您有)。

相关内容

  • 没有找到相关文章