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

如何使用Spring MockMvc与JsonPath测试响应字段的不等性?

解决Spring MVC测试中jsonPath不等于匹配的Mockito异常问题

问题场景

测试接口响应的errorMessage字段不等于特定值时,使用Mockito的AdditionalMatchers.not()配合jsonPath断言,触发了如下异常:

org.mockito.exceptions.misusing.InvalidUseOfMatchersException: 
No matchers found for additional matcher Not(?)

原测试代码:

@Test
void whenAnAuth0ExceptionIsThrown_itShouldNotLeakInformation() throws Exception {
    String description = "Resource not found.";
    Auth0Exception auth0Exception = new Auth0Exception(description);

    when(usersService.getRoles()).thenThrow(new UnrecoverableAuthException("api exception", auth0Exception));

    mockMvc.perform(get("/v1/users/roles").with(csrf()))
        .andExpect(status().isInternalServerError())
        .andExpect(jsonPath("$.errorMessage").value(AdditionalMatchers.not(description)));


    verify(usersService).getRoles();
}

问题原因

AdditionalMatchers.not()是Mockito专属的匹配器,而Spring MVC Test的jsonPath().value()方法仅支持Hamcrest匹配器,两者不兼容导致抛出匹配器使用错误。

最优解决方案

改用Hamcrest框架提供的not()匹配器,它可以直接和jsonPath配合使用,无需额外处理:

// 引入Hamcrest的not匹配器
import static org.hamcrest.Matchers.not;

@Test
void whenAnAuth0ExceptionIsThrown_itShouldNotLeakInformation() throws Exception {
    String description = "Resource not found.";
    Auth0Exception auth0Exception = new Auth0Exception(description);

    when(usersService.getRoles()).thenThrow(new UnrecoverableAuthException("api exception", auth0Exception));

    mockMvc.perform(get("/v1/users/roles").with(csrf()))
        .andExpect(status().isInternalServerError())
        // 使用Hamcrest的not匹配器替代Mockito的AdditionalMatchers.not()
        .andExpect(jsonPath("$.errorMessage").value(not(description)));


    verify(usersService).getRoles();
}

替代方案(你提到的临时方法)

如果不想依赖Hamcrest,也可以通过MvcResult手动解析响应内容进行断言:

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import static org.junit.jupiter.api.Assertions.assertNotEquals;

@Test
void whenAnAuth0ExceptionIsThrown_itShouldNotLeakInformation() throws Exception {
    String description = "Resource not found.";
    Auth0Exception auth0Exception = new Auth0Exception(description);

    when(usersService.getRoles()).thenThrow(new UnrecoverableAuthException("api exception", auth0Exception));

    // 获取请求结果
    MvcResult result = mockMvc.perform(get("/v1/users/roles").with(csrf()))
        .andExpect(status().isInternalServerError())
        .andReturn();

    // 解析响应JSON
    String responseBody = result.getResponse().getContentAsString();
    JsonNode jsonNode = new ObjectMapper().readTree(responseBody);
    String errorMessage = jsonNode.get("errorMessage").asText();

    // 断言字段不等于目标值
    assertNotEquals(description, errorMessage);

    verify(usersService).getRoles();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 08:50:38