Spring测试中如何Mock方法内的Mapper?解决空指针异常
问题解决指南
首先,你遇到的NullPointerException是因为Mock的envoyerMessage默认返回null,后续调用sendedMessageId.getValue()触发空指针。以下是分步解决方案:
1. 修复空指针异常
在测试方法中,用Mockito为envoyerMessage.execute()方法设置返回值,避免返回null:
import static org.mockito.Mockito.any; import static org.mockito.Mockito.when; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; // 其他必要导入 @Test public void send() throws Exception { // 修正JSON语法错误(原JSON中id字段的1""是非法格式) String content = "{ \"id\": 1, \"message\": \"Test variable\" }"; // 构造模拟的MessageId实例(根据你的实际类结构调整) MessageId mockMessageId = new MessageId(2L); // 让envoyerMessage.execute()返回模拟的MessageId when(envoyerMessage.execute(any(Message.class))).thenReturn(mockMessageId); this.mockMvc.perform( post("/api/message/add") .contentType(MediaType.APPLICATION_JSON) .content(content) .accept(MediaType.APPLICATION_JSON)) // 原接口返回HttpStatus.CREATED(201),不是200,修正断言 .andExpect(status().isCreated()); }
2. Mock WebMessageMapper
根据你的Mapper实现方式,分两种情况处理:
情况1:Mapper是Spring管理的Bean(如MapStruct指定componentModel="spring")
直接将Mapper声明为@MockBean,然后Stub转换方法:
@Tag("unitTest") @WebMvcTest(MessageControllerV1.class) public class MessageControllerV1Test { @Autowired private MockMvc mockMvc; @MockBean private EnvoyerMessage envoyerMessage; @MockBean private LireMessage lireMessage; // 添加MockBean注解 @MockBean private WebMessageMapper webMessageMapper; @Test public void send() throws Exception { String content = "{ \"id\": 1, \"message\": \"Test variable\" }"; MessageId mockMessageId = new MessageId(2L); Message mockMessage = new Message(); mockMessage.setMessage("Test variable"); // Stub转换方法 when(webMessageMapper.messageDtoToMessage(any(MessageDto.class))).thenReturn(mockMessage); when(envoyerMessage.execute(any(Message.class))).thenReturn(mockMessageId); this.mockMvc.perform( post("/api/message/add") .contentType(MediaType.APPLICATION_JSON) .content(content) .accept(MediaType.APPLICATION_JSON)) .andExpect(status().isCreated()); } }
情况2:Mapper是静态单例(如默认MapStruct实例)
使用Mockito的mockStatic来Mock静态实例:
import org.mockito.MockedStatic; // 其他必要导入 @Test public void send() throws Exception { String content = "{ \"id\": 1, \"message\": \"Test variable\" }"; MessageId mockMessageId = new MessageId(2L); Message mockMessage = new Message(); mockMessage.setMessage("Test variable"); // Mock静态的WebMessageMapper.INSTANCE try (MockedStatic<WebMessageMapper> mockedMapper = org.mockito.Mockito.mockStatic(WebMessageMapper.class)) { WebMessageMapper mockMapper = org.mockito.Mockito.mock(WebMessageMapper.class); mockedMapper.when(WebMessageMapper::INSTANCE).thenReturn(mockMapper); when(mockMapper.messageDtoToMessage(any(MessageDto.class))).thenReturn(mockMessage); when(envoyerMessage.execute(any(Message.class))).thenReturn(mockMessageId); this.mockMvc.perform( post("/api/message/add") .contentType(MediaType.APPLICATION_JSON) .content(content) .accept(MediaType.APPLICATION_JSON)) .andExpect(status().isCreated()); } }
内容的提问来源于stack exchange,提问作者mtnp
相关产品推荐
相关产品推荐

