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

邮件发送失败测试返回HTTP 200而非500问题排查

问题分析与解决方案

核心原因1:Mockito参数匹配器不匹配null值

你的测试中使用anyList()作为参数匹配器,但Mockito的anyList()默认不匹配null值——而控制器传入的ccEmails和bccEmails是null(测试用例未设置这两个字段)。这导致你配置的doThrow逻辑未被触发,emailOperations.sendBasicEmail()方法没有抛出异常,控制器正常执行并返回200。

修复方法

将mock中的anyList()替换为支持null的匹配器:

  • 若使用Mockito 4.6+,可用anyList().nullable()
  • 通用兼容写法:用any()或nullable(List.class)

修改后的mock代码:

doThrow(new EmailSendingException("Failed to send email")).when(emailOperations)
        .sendBasicEmail(anyString(), nullable(List.class), nullable(List.class), anyString(), anyString(), anyBoolean());

核心原因2:测试断言与异常处理器返回格式不匹配

你的测试断言期望返回字符串"Failed to send email. Please try again later.",但异常处理器实际返回的是ErrorResponse对象的JSON结构。即使异常被正确抛出,这个断言也会失败。

修复方法

改用JSON断言验证响应内容:

.andExpect(status().isInternalServerError())
.andExpect(jsonPath("$.code").value("EMAIL_SENDING_FAILED"))
.andExpect(jsonPath("$.message").value("Failed to send email"));

注:需确保测试类引入了Spring MVC的JSON断言支持(@SpringBootTest或@WebMvcTest会自动包含)。

额外检查:异常处理器是否正确注册

确认异常处理器类上添加了@RestControllerAdvice(或@ControllerAdvice)注解,否则Spring无法识别该全局异常处理逻辑:

@RestControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(EmailSendingException.class)
    public ResponseEntity<ErrorResponse> handleEmailSendingException(EmailSendingException ex) {
        logger.error("Email sending failed: {}", ex.getMessage(), ex);
        ErrorResponse errorResponse = new ErrorResponse("EMAIL_SENDING_FAILED", ex.getMessage());
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorResponse);
    }
}

修改后的完整测试用例

@Test
@WithMockUser(username = "admin", roles = {"ADMIN"})
void testSendBasicEmail_Failure() throws Exception {
    // Arrange
    BasicEmailRequest request = new BasicEmailRequest();
    request.setToEmail("test@example.com");
    request.setSubject("Test Subject");
    request.setBody("Test Body");
    request.setIsHtml(false);
    
    doThrow(new EmailSendingException("Failed to send email")).when(emailOperations)
            .sendBasicEmail(anyString(), nullable(List.class), nullable(List.class), anyString(), anyString(), anyBoolean());

    // Act & Assert
    mockMvc.perform(post("/api/email/sendBasic")
                    .with(csrf())
                    .contentType(MediaType.APPLICATION_JSON)
                    .content(objectMapper.writeValueAsString(request)))
            .andExpect(status().isInternalServerError())
            .andExpect(jsonPath("$.code").value("EMAIL_SENDING_FAILED"))
            .andExpect(jsonPath("$.message").value("Failed to send email"));
    
    verify(emailOperations, times(1)).sendBasicEmail(
            "test@example.com", null, null, "Test Subject", "Test Body", false);
}

内容的提问来源于stack exchange,提问作者Vasco Oliveira

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 05:07:19