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

Mockito无法捕获抛出异常,测试出现AssertionError问题求助

单元测试异常捕获失败排查建议

问题背景

编写失败场景单元测试时,期望捕获com.orgfoo.BarService.order.service.exception.ErrorJsonProcessingException,但实际触发AssertionError,提示未捕获到预期异常。尝试处理JsonProcessingException后问题仍存在。

异常信息

exception: com.orgfoo.BarService.order.service.exception.ErrorJsonProcessingException
java.lang.AssertionError: Expected exception: com.orgfoo.BarService.order.service.exception.ErrorJsonProcessingException

测试类代码

@Test(expected = ErrorJsonProcessingException.class)
public void testEmailOnBar_JsonProcessingException() throws Exception {
    // Given
    EmailOnBarRequest request = new EmailOnBarRequest();
    HttpHeaders httpHeaders = getHttpHeaders();
    when(BarServiceServiceConfig.getEmailOnBarUrl()).thenReturn("orgbar/rp-webapp-9-common/ecommerce/wireless/order/emailOnBar?lo=%s&sc=%s");

    BarResponse BarResponse = new BarResponse();
    BarResponse.setMessage("testValue");

    when(orgbarServiceConnector.getBiporgbarResponse(anyString(), any(HttpEntity.class), any(HttpHeaders.class), any(HttpMethod.class))).thenReturn(BarResponse);
    when(mapper.readValue(anyString(), eq(ImplEmailOnBarOutput.class))).thenThrow(new JsonProcessingException("test") {});

    // When
    orderProcessor.emailOnBar(request, httpHeaders, "salesChannel", "lo");
}

被测系统(SUT)代码

@InjectMocks
private OrderProcessor orderProcessor;

@Mock
private orgbarServiceConnector orgbarServiceConnector;

@Mock
private BarServiceServiceConfig BarServiceServiceConfig;

@Mock
private ObjectMapper mapper;

@Mock
private ObjectWriter objectWriter;

@Autowired
private orgbarServiceConnector orgbarServiceConnector;

@Autowired
private BarServiceServiceConfig BarServiceServiceConfig;

@Autowired
private static ObjectMapper mapper;

@Autowired
private static ObjectWriter objectWriter;

static {
    if (mapper == null)
        mapper = new ObjectMapper();
    if (objectWriter == null)
        objectWriter = mapper.writer().withDefaultPrettyPrinter();
}

public ImplEmailOnBarOutput emailOnBar(EmailOnBarRequest input, HttpHeaders httpHeaders, String sc, String lo) {
    try {
        LOGGER.debug("Entering emailOnBar method with input: {}, lo: {}, salesChannel: {}", objectWriter.writeValueAsString(input), lo, sc);

        String url = String.format(BarServiceServiceConfig.getEmailOnBarUrl(), lo, sc);
        LOGGER.debug("Calling orgbar API with URI: {}", url);

        BarResponse BarResponse = orgbarServiceConnector.getOrgbarResponse(url, new HttpEntity<>(input), httpHeaders, HttpMethod.POST);    
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        return mapper.readValue(objectWriter.writeValueAsString(BarResponse), ImplEmailOnBarOutput.class);
    } catch (JsonProcessingException e) {
        LOGGER.error("Exception while calling orgbar-emailOnBar api exception={}", e);
        throw new ErrorJsonProcessingException(e, JSON_PROCESSEING_ERROR_MSG, orgbar_SERVICE);
    }
}

POJO代码

@NoArgsConstructor
@AllArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ImplEmailOnBarOutput {
    @JsonProperty("__EmptyObject__")
    private EmptyObject emptyObject;
}

@Data
@NoArgsConstructor
@JsonSerialize
public class EmptyObject {

}

排查建议与调试方案

核心问题排查点

  • Mock对象未生效:被测类同时存在@Autowired和@Mock标注的字段(如mapper、orgbarServiceConnector),Spring会优先注入真实Bean而非Mock实例,导致测试中配置的thenThrow逻辑不执行。需确保测试类使用@RunWith(MockitoJUnitRunner.class)或@ExtendWith(MockitoExtension.class),并移除被测类中静态@Autowired字段和初始化块,避免真实对象覆盖Mock实例。
  • 方法调用匹配失败:测试中Mock的是orgbarServiceConnector.getBiporgbarResponse(),但被测代码调用的是orgbarServiceConnector.getOrgbarResponse(),方法名不匹配导致Mock逻辑未触发。需修正测试中的Mock方法名,与被测代码调用的方法完全一致。
  • 异常捕获方式优化:改用assertThrows替代@Test(expected = ...),更精准地捕获并验证异常,示例:
    @Test
    public void testEmailOnBar_JsonProcessingException() throws Exception {
        // Given逻辑保持不变
        // When & Then
        assertThrows(ErrorJsonProcessingException.class, () -> {
            orderProcessor.emailOnBar(request, httpHeaders, "salesChannel", "lo");
        });
    }
    

调试优化方案

  • 启用Mockito调试日志:配置日志级别为DEBUG,查看Mock对象的调用情况,确认方法是否被正确匹配。
  • 分步验证Mock逻辑:单独测试每个Mock方法的调用,例如先验证BarServiceServiceConfig.getEmailOnBarUrl()是否返回预期URL,再验证orgbarServiceConnector的方法是否被调用。
  • 添加断点验证异常流:在被测类的catch块中添加断点,确认JsonProcessingException是否被捕获并转换为ErrorJsonProcessingException抛出。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 18:15:19