You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot 2.7集成JUnit测试时出现‘Content type not set’错误的解决方案咨询

问题根源分析

嘿,我一眼就揪出问题所在了——你的测试逻辑和Controller的实际执行路径完全不匹配!

看你测试代码里的这段mock:

when(employeeService.findByEmail(any(String.class))).thenReturn(Optional.of(employee));

这相当于模拟了「数据库里已经存在这个邮箱的员工」的场景,此时Controller会触发这段分支:

if (!employeeDb.isEmpty()) {
    return new ResponseEntity<>(HttpStatus.CONFLICT);
}

这个返回的ResponseEntity只带了409冲突状态码,既没有响应体,也没设置Content-Type。但你的测试却硬要断言:

.andExpect(status().isOk())
.andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON))

一边期望200成功状态,一边检查Content-Type,这不报错才怪——409响应根本就没这个属性啊!


解决方案(两种场景二选一)

根据你实际的测试目标,有两个修改方向:

场景1:测试「添加重复员工返回冲突」

如果你的本意就是验证重复添加的冲突场景,直接调整测试的断言逻辑就行:

@Test
void addEmployee_duplicateEmail_returnsConflict() throws Exception {
    when(employeeService.findByEmail(any(String.class))).thenReturn(Optional.of(employee));

    ObjectMapper objectMapper = new ObjectMapper();
    String json = objectMapper.writeValueAsString(employeeDto);

    mockMvc.perform(
            MockMvcRequestBuilders
                    .post(REST_URL)
                    .contentType(MediaType.APPLICATION_JSON)
                    .accept(MediaType.APPLICATION_JSON)
                    .characterEncoding("utf-8")
                    .content(json)
    )
            .andExpect(status().isConflict()); // 改成期望409状态码
    // 删掉所有检查响应体的断言,因为冲突响应没有body
}

场景2:测试「添加新员工成功」

如果本来是想验证正常添加的成功流程,那得修改mock逻辑,让findByEmail返回空的Optional,这样Controller才会走保存分支,返回带Content-Type的200响应:

@Test
void addEmployee_newEmployee_returnsOk() throws Exception {
    when(employeeService.save(employeeDto.toEmployee())).thenReturn(employee);
    // 这里改一下:返回空Optional,表示数据库中无该员工
    when(employeeService.findByEmail(any(String.class))).thenReturn(Optional.empty());

    ObjectMapper objectMapper = new ObjectMapper();
    String json = objectMapper.writeValueAsString(employeeDto);

    mockMvc.perform(
            MockMvcRequestBuilders
                    .post(REST_URL)
                    .contentType(MediaType.APPLICATION_JSON)
                    .accept(MediaType.APPLICATION_JSON)
                    .characterEncoding("utf-8")
                    .content(json)
    )
            .andExpect(status().isOk())
            .andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON))
            .andExpect(jsonPath("$.firstname", is(employee.getFirstname())))
            .andExpect(jsonPath("$.lastname", is(employee.getLastname())))
            .andExpect(jsonPath("$.email", is(employee.getEmail())));
}

额外优化(可选)

如果希望冲突响应也能带上Content-Type,可以调整Controller的返回逻辑:

if (!employeeDb.isEmpty()) {
    return ResponseEntity.status(HttpStatus.CONFLICT)
            .contentType(MediaType.APPLICATION_JSON)
            .build();
}

不过这不是必须的,完全看你的业务需求。

内容的提问来源于stack exchange,提问作者poub 770

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 12:57:38