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

Java 在SpringRest中编写行为JUnit测试有什么意义?,java,spring,unit-testing,junit,mockito,Java,Spring,Unit Testing,Junit,Mockito,我是JUnitMockito的新手,我为我的SpringREST资源编写了这个测试函数 @Test public void getAllMessageHappyTest() throws Exception { List<Message> messageList = new ArrayList<>(); messageList.add(new Message(1,"Hello")); messageList.add(new Message(5,"H

我是JUnitMockito的新手,我为我的SpringREST资源编写了这个测试函数

@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);
}
@测试
public void getAllMessageHappyTest()引发异常{
List messageList=new ArrayList();
添加(新消息(1,“你好”);
添加(新消息(5,“Hello world”);
添加(新消息(3,“你好,世界,G!”);
当(messageService.getAllMessages())。然后返回(messageList);
RequestBuilder RequestBuilder=MockMvcRequestBuilders.get(“/messages/”).accept(MediaType.APPLICATION\u JSON);
MvcResult MvcResult=mockMvc.perform(requestBuilder.andReturn();
字符串应为=”;//应为
JSONAssert.assertEquals(应为mvcResult.toString(),false);
}

在上面的场景中,我有
when(messageService.getAllMessages())。然后返回(messageList)
返回由我(或团队成员)编写的
消息列表
,我将返回的
JSON
与预期的
字符串进行比较,该字符串也将由我(或团队成员)编写。所以这两个问题都是由同一个人写的,那么进行这样的测试有什么意义呢;因为编写测试的人也会硬编码(以JSON字符串的形式),所以测试可能是多余的,或者至少可能具有有限的价值。也许您的问题的子文本是,既然编写底层端点的人将提供预期,那么它必须通过,如果它的成功是命中注定的,那么它就没有什么价值

但是,无论是谁编写测试和谁编写测试下的代码,上面显示的示例测试都有价值,因为:

  • 它测试的不仅仅是返回的JSON,它还测试。。。
    • REST端点映射是否正确,即它公开了一个名为
      “/messages/”
      的端点,该端点接受JSON
    • REST层使用一个serialiser来生成一些JSON
  • 继续运行此测试用例将确保即使在您(或您的团队的其他成员)不再处理此代码或换句话说,此端点的预期行为继续得到满足;它起着回归安全网的作用
  • 被测试的代码将来可能会被更改,如果是这样,那么这个测试用例提供了一个基线,将来可以根据它进行开发
  • 测试用例为您的代码提供了一种文档形式;不熟悉此代码库的人可以查看测试以了解代码的预期行为
此外,此测试用例可以扩展为包括sad路径的测试,例如无效重复、不安全的访问尝试等,从而提高测试覆盖率

更新1:回应此评论:


即使有人在实际代码中进行了更改,并且现在在生成实际代码之后生成了一种不同类型的JSON(比如说不符合要求),即使如此,测试用例也会通过,因为此时是硬编码的,预期也是硬编码的。那么重点是什么呢

这样的测试显然毫无意义:

String json = "...";

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

assertEquals(json, foo.getJson());

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

测试中硬编码的行为是针对某些服务的,这将测试控制器层。即使有人在实际代码中进行了更改,并且现在在生成实际代码后生成了不同类型的JSON(比如不按要求),即使如此,测试用例也将通过,因为
当then是硬编码的时候
预期的时候
也是硬编码的。那么重点是什么呢?