我正在设置一个integrationtest来检查spring应用程序是否在控制器级别工作,旁边是我的单元测试。我确实知道我正在测试的工作,单元测试工作,我已经用postman做了所有的事情。每个integrationtest也单独工作,并给出我期望它给出的结果。问题是当我一起运行它们时,有些测试不再工作了。这是因为MockMvc应该在每次测试时都被更新,但事实并非如此。
我尝试通过手动设置mockMvc来获得这种行为,而不是将其注入到构造函数中,但同样的行为仍然存在。我想我设置MockMvc是错误的,但我似乎无法弄清楚如何正确设置它。我使用Sping Boot 3和Java 20。
我应该如何创建mock,以便它在每个测试中再次运行,并且不会受到其他测试的影响?我将testclass放在下面。
@SpringBootTest
@AutoConfigureMockMvc
public class EmployeeControllorIntegrationTest {
private final static String URI = "/employees/";
private ObjectMapper objectMapper;
private MockMvc mockMvc;
public EmployeeControllorIntegrationTest(MockMvc mockMvc, ObjectMapper objectMapper) {
this.mockMvc = mockMvc;
this.objectMapper = objectMapper;
}
@Test
void getAllEmployeesThrowsExceptionWhenEmpty() throws Exception{
String error = mockMvc.perform(get(URI+"showAll"))
.andExpect(status().isAccepted())
.andExpect(content().contentType("application/json"))
.andReturn().getResolvedException().getMessage();
assertThat(error).isEqualTo("No employees present");
}
@Test
void getAllEmployeesWorksWhenEmployeesPresent() throws Exception{
this.insertUnitAndLevel();
EmployeeDto employeeDto = new EmployeeDto("employeeName", "employeeNameSurname", LocalDate.of(2000,04,23),1L,1L);
mockMvc.perform(post(URI+"addEmployee")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(employeeDto)));
MockHttpServletResponse response = mockMvc.perform(get(URI+"showAll"))
.andExpect(status().isOk())
.andExpect(content().contentType("application/json"))
.andReturn().getResponse();
Employee[] allLevels = objectMapper.readValue(response.getContentAsString(), Employee[].class);
assertThat(allLevels).hasSize(1);
assertThat(Arrays.stream(allLevels).findFirst().get().getName()).isEqualTo("employeeName");
assertThat(Arrays.stream(allLevels).findAny().get().getName()).isEqualTo("employeeName");
assertThat(Arrays.stream(allLevels).findFirst().get().getStartDateContract()).isEqualTo(LocalDate.now());
assertThat(Arrays.stream(allLevels).findAny().get().getStartDateContract()).isEqualTo(LocalDate.now());
}
@Test
void addNewEmployeeWithInvalidNameThrowsError() throws Exception{
this.insertUnitAndLevel();
EmployeeDto employeeDto = new EmployeeDto(" ", "employeeNameSurname", LocalDate.of(2000,04,23),1L,1L);
String error = mockMvc.perform(post(URI+"addEmployee")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(employeeDto)))
.andExpect(status().isBadRequest())
.andExpect(content().contentType("application/json"))
.andReturn().getResolvedException().getMessage();
assertThat(error).isEqualTo("Cannot be empty or blank");
}
@Test
void addNewEmployeeWithInvalidSurnameThrowsError() throws Exception{
this.insertUnitAndLevel();
EmployeeDto employeeDto = new EmployeeDto("employeeName", " ", LocalDate.of(2000,04,23),1L,1L);
String error = mockMvc.perform(post(URI+"addEmployee")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(employeeDto)))
.andExpect(status().isBadRequest())
.andExpect(content().contentType("application/json"))
.andReturn().getResolvedException().getMessage();
assertThat(error).isEqualTo("Cannot be empty or blank");
}
@Test
void addingNewEmployeeWithAlreadyExistingNameSurnameAndBirthdateThrowsError() throws Exception{
this.insertUnitAndLevel();
EmployeeDto employeeDto = new EmployeeDto("employeeName", "employeeSurname", LocalDate.of(2000,04,23),1L,1L);
EmployeeDto employeeDtoCopy = new EmployeeDto("employeeName", "employeeSurname", LocalDate.of(2000,04,23),1L,1L);
mockMvc.perform(post(URI+"addEmployee")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(employeeDto)));
String error = mockMvc.perform(post(URI+"addEmployee")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(employeeDtoCopy)))
.andExpect(status().isConflict())
.andExpect(content().contentType("application/json"))
.andReturn().getResolvedException().getMessage();
assertThat(error).isEqualTo("employee with that name, surname and date of birth already exists");
}
@Test
void addingValidEmployeeWorks() throws Exception{
this.insertUnitAndLevel();
EmployeeDto employeeDto = new EmployeeDto("employeeName", "employeeSurname", LocalDate.of(2000,04,23),1L,1L);
mockMvc.perform(post(URI+"addEmployee")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(employeeDto)))
.andExpect(status().isOk())
.andExpect(content().contentType("text/plain;charset=UTF-8"))
.andExpect(content().string("New employee added succesfully"));
}
private void insertUnitAndLevel() throws Exception{
EnumerationLevel mocklevel = new EnumerationLevel("A1", "Mockdescripition");
mockMvc.perform(post("/units/addUnit")
.contentType(MediaType.APPLICATION_JSON)
.content("new unit"));
mockMvc.perform(post("/levels/addLevel")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(mocklevel)));
}
}
2条答案
按热度按时间u3r8eeie1#
使用
MockMvcBuilders
你可以创建mockMvc
对象。你需要自动连接WebApplicationContext
。如果还想应用安全性,则使用
这将分别为每个测试用例生成
MockMvc
对象。wswtfjt72#
手动清除db很有帮助。在每次测试之前示例化mock是不必要的,只需将其注入构造函数并清除db即可。尽管spring docs声明如Dhaval所说的那样示例化mock,但这并没有在使用后清空mock。我将其注入构造函数并使用@AutoConfigureMockMvc annotation。然后在每次测试之前清除db,它就可以工作了。
将jdbcTemplate设置为变量并将其注入到构造函数中也可以工作