简体   繁体   English

如何使用 mockMvc 检查响应正文中的值 - AssertionError: Status expected:<201> but was:<400>

[英]How to check values in response body with mockMvc - AssertionError: Status expected:<201> but was:<400>

im new to test writing and i am trying to write junit tests for my controller class using mockMvc.我是测试写作的新手,我正在尝试使用 mockMvc 为我的 controller class 编写 junit 测试。

Here are my classes:这是我的课程:

public class StudentDTO {

private final String firstName;
private final String lastName;
private final String JMBAG;
private final Integer numberOfECTS;
private final boolean tuitionShouldBePaid;}

Command class指令 class

public class StudentCommand { 
@NotBlank (message = "First name must not be empty!")
private String firstName;

@NotBlank (message = "Last name must not be empty!")
private String lastName;


@NotNull(message = "Date of birth must be entered!")
@Past(message = "Date of birth must be in the past!")
private LocalDate dateOfBirth;

@NotBlank(message = "JMBAG must not be empty!")
@Pattern(message = "JMBAG must have 10 digits", regexp = "[\\d]{10}")
private String jmbag;

@NotNull(message = "Number of ECTS points must be entered!")
@PositiveOrZero(message = "Number of ECTS points must be entered as a positive integer!")
private Integer numberOfECTS;}

Controller class: Controller class:

@Secured({"ROLE_ADMIN"})
@PostMapping
public ResponseEntity<StudentDTO> save(@Valid @RequestBody final StudentCommand command){
    return studentService.save(command)
            .map(
                    studentDTO -> ResponseEntity
                            .status(HttpStatus.CREATED)
                            .body(studentDTO)
            )
            .orElseGet(
                    () -> ResponseEntity
                            .status(HttpStatus.CONFLICT)
                            .build()
            );
}

Test class:测试 class:

@SpringBootTest
@AutoConfigureMockMvc class StudentControllerTest {
@Autowired
private MockMvc mockMvc;

@MockBean
private StudentService studentServiceMock;

@Autowired
private ObjectMapper objectMapper;

private final String TEST_FIRST_NAME = "Marry";
private final String TEST_LAST_NAME = "Blinks";
private final String TEST_JMBAG = "0025478451";
private final Integer TEST_NUMBER_OF_ECTS = 55;
private final boolean TEST_TUITION_SHOULD_BE_PAID = true;
private final LocalDate TEST_DATE_OF_BIRTH = LocalDate.parse("1999-01-12");

@Test
void testSave() throws Exception {

    StudentCommand studentCommand = new StudentCommand(TEST_FIRST_NAME,TEST_LAST_NAME,TEST_DATE_OF_BIRTH,TEST_JMBAG,TEST_NUMBER_OF_ECTS);

    this.mockMvc.perform(
            post("/student")
                    .with(user("admin")
                            .password("test")
                            .roles("ADMIN")
                    )
                    .with(csrf())
            .contentType(MediaType.APPLICATION_JSON)
            .content(objectMapper.writeValueAsString(studentCommand))
            .accept(MediaType.APPLICATION_JSON)
    )
            .andExpect(status().isCreated())
            .andExpect(content().contentType(MediaType.APPLICATION_JSON))
            .andExpect(jsonPath("$.jmbag").value(TEST_JMBAG))
            .andExpect(jsonPath("$.firstName").value(TEST_FIRST_NAME))
            .andExpect(jsonPath("$.lastName").value(TEST_LAST_NAME));
}

I always get test failed with this error:我总是因为这个错误而测试失败:


MockHttpServletRequest:
      HTTP Method = POST
      Request URI = /student
       Parameters = {_csrf=[30de7a8f-a3d5-429d-a778-beabd1a533da]}
          Headers = [Content-Type:"application/json;charset=UTF-8", Accept:"application/json", Content-Length:"272"]
             Body = {"firstName":"Marry","lastName":"Blinks","dateOfBirth":{"year":1999,"month":"JANUARY","monthValue":1,"dayOfMonth":12,"chronology":{"id":"ISO","calendarType":"iso8601"},"dayOfWeek":"TUESDAY","leapYear":false,"dayOfYear":12,"era":"CE"},"jmbag":"0025478451","numberOfECTS":55}
    Session Attrs = {}
Handler:
             Type = com.studapp.students.StudentController
           Method = com.studapp.students.StudentController#save(StudentCommand)
MockHttpServletResponse:
           Status = 400
    Error message = null
          Headers = [Vary:"Origin", "Access-Control-Request-Method", "Access-Control-Request-Headers", X-Content-Type-Options:"nosniff", X-XSS-Protection:"1; mode=block", Cache-Control:"no-cache, no-store, max-age=0, must-revalidate", Pragma:"no-cache", Expires:"0", X-Frame-Options:"DENY"]
     Content type = null
             Body = 
    Forwarded URL = null
   Redirected URL = null
          Cookies = []
java.lang.AssertionError: Status expected:<201> but was:<400>
Expected :201
Actual   :400

I am not sure why it fails.我不确定它为什么会失败。 Why is response body blank?为什么响应正文为空白? I dont want to call my service because im not testing it, but i feel like i should call it somehow(but then again, im not testing the service).我不想调用我的服务,因为我没有测试它,但我觉得我应该以某种方式调用它(但话又说回来,我没有测试服务)。 Any suggestion would be appreciated.任何建议将不胜感激。

You should use @Autowired on your ObjectMapper to make sure it is configured in the same way by Spring as it would be during the application runtime.您应该在ObjectMapper上使用@Autowired以确保 Spring 以与应用程序运行时相同的方式对其进行配置。 This would explain the 400 - Bad request error you are getting.这将解释您收到的 400 - Bad request 错误。

The fact that it is a 409 - Conflict after autowiring the ObjectMapper suggests that this was indeed the error.自动装配ObjectMapper后它是 409 - Conflict 的事实表明这确实是错误。 Since you do not configure your studentServiceMock in the test, the 409 seems to be the apporiate answer from the controller, because the orElseGet part is being executed.由于您没有在测试中配置studentServiceMock ,因此 409 似乎是 controller 的合适答案,因为正在执行orElseGet部分。

If I am not mistaken, you could slim down the test class annotations a little and only use @WebMvcTest .如果我没记错的话,您可以稍微减少测试 class 注释,只使用@WebMvcTest This should suffice for this kind of test and it should be a little faster.这对于这种测试应该足够了,而且速度应该更快一些。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM