Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/spring-boot/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring boot 在SpringMVC集成测试中处理我的自定义异常_Spring Boot_Spring Mvc_Spring Test_Junit5_Spring Test Mvc - Fatal编程技术网

Spring boot 在SpringMVC集成测试中处理我的自定义异常

Spring boot 在SpringMVC集成测试中处理我的自定义异常,spring-boot,spring-mvc,spring-test,junit5,spring-test-mvc,Spring Boot,Spring Mvc,Spring Test,Junit5,Spring Test Mvc,我在控制器类中有以下方法: @PostMapping("employees") @ResponseStatus(HttpStatus.CREATED) public Employee addEmployee(@Valid @RequestBody Employee employee) { try { return employeeRepository.save(employee); } catch (DataIntegrityViolationExceptio

我在控制器类中有以下方法:

@PostMapping("employees")
  @ResponseStatus(HttpStatus.CREATED)
  public Employee addEmployee(@Valid @RequestBody Employee employee) {
    try {
      return employeeRepository.save(employee);
    } catch (DataIntegrityViolationException e) {
      e.printStackTrace();
      Optional<Employee> existingEmployee = employeeRepository.findByTagId(employee.getTagId());
      if (!existingEmployee.isPresent()) {
        //The exception root cause was not due to a unique ID violation then
        throw e;
      }
      throw new DuplicateEntryException(
          "An employee named " + existingEmployee.get().getName() + " already uses RFID tagID " + existingEmployee.get().getTagId());
    }
  }
多亏了
@ResponseStatus(HttpStatus.CONFLICT)
行,当我手动测试该方法时,我得到了带有时间戳、状态、错误、消息和路径字段的默认spring引导REST消息

我仍然熟悉春季的测试,我有这个测试:

@Test
  public void _02addEmployee_whenDuplicateTagId_thenExceptionIsReturned() throws Exception {
    Employee sampleEmployee = new Employee("tagId01", "John Doe");
    System.out.println("Employees in the database: " + repository.findAll().size()); //prints 1
    // @formatter:off
    mvc.perform(post("/employees").contentType(MediaType.APPLICATION_JSON).content(JsonUtil.toJson(sampleEmployee)))
       .andExpect(status().isConflict())
       .andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON))
       .andExpect(jsonPath("$.message").value("An employee named John Doe already uses RFID tagID tagId01"));
    // @formatter:on

    int employeeCount = repository.findAll().size();
    Assert.assertEquals(1, employeeCount);
  }
正如您所猜测的,有另一个测试首先运行,名为
\u 01addEmployee\u当验证输入时,然后创建employee()
,它插入一个具有相同标记ID的员工,该标记ID在测试2中使用。测试#1通过,但测试#2未通过,因为HTTP响应如下所示:

MockHttpServletResponse:
           Status = 409
    Error message = null
          Headers = {}
     Content type = null
             Body = 
    Forwarded URL = null
   Redirected URL = null
          Cookies = []
在上述响应之前的控制台中,我看到:

Resolved Exception:
             Type = ai.aitia.rfid_employee.exception.DuplicateEntryException
所以我的第二个测试失败了,因为
java.lang.AssertionError:Content-type-not-set
。 与手动测试相比,是什么导致不同的行为?为什么不退回

{
    "timestamp": "2019-01-03T09:47:33.371+0000",
    "status": 409,
    "error": "Conflict",
    "message": "An employee named John Doe already uses RFID tagID tagId01",
    "path": "/employees"
}
更新:我在不同的REST端点上也经历了同样的事情,测试用例导致了我自己的
ResourceNotFoundException
,但MockMvc对象没有收到实际的JSON错误对象

更新2:以下是我对测试类的类级注释:

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, classes = RfidEmployeeApplication.class)
@AutoConfigureMockMvc
@AutoConfigureTestDatabase
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@TestPropertySource(locations = "classpath:application-test.properties")

org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController\error
填写错误响应正文的完整信息,但对于
MockMvc
它不起作用。我刚刚检查了您在本例中是否可以轻松使用
testrestemplate

首先只需
@Autowired private testrestemplate testrestemplate在测试类中

并修改您的测试方法,例如:

ResponseEntity<String> response = testRestTemplate.postForEntity("/employees", sampleEmployee, String.class);
        String message = com.jayway.jsonpath.JsonPath.read(response.getBody(), "$.message");
        String expectedMessage = "An employee named John Doe already uses RFID tagID tagId01";
        Assert.assertEquals(expectedMessage, message);
        Assert.assertTrue(response.getStatusCode().is4xxClientError());
ResponseEntity response=testRestTemplate.postForEntity(“/employees”,sampleEmployees,String.class”);
String message=com.jayway.jsonpath.jsonpath.read(response.getBody(),“$.message”);
String expectedMessage=“一名名名为John Doe的员工已使用RFID tagID tagId01”;
Assert.assertEquals(预期消息、消息);
Assert.assertTrue(response.getStatusCode().is4xxClientError());

例如,你使用的是@RestController还是@Controller?是的,我说的前一个,就是我已经在使用的那个。你有没有尝试过@PostMapping(value=“employees”,products=“application/json”)?我刚试过,没有什么不同。非常感谢你的持续帮助。我想知道我是否应该停止使用MockMvc,转而使用TestRestTemplate。尽管阅读了相关内容,但在服务器端测试中,似乎最好尽可能继续使用MockMvc。
ResponseEntity<String> response = testRestTemplate.postForEntity("/employees", sampleEmployee, String.class);
        String message = com.jayway.jsonpath.JsonPath.read(response.getBody(), "$.message");
        String expectedMessage = "An employee named John Doe already uses RFID tagID tagId01";
        Assert.assertEquals(expectedMessage, message);
        Assert.assertTrue(response.getStatusCode().is4xxClientError());