Spring Boot中JUnit测试如何传递非空HttpSession对象
在Spring Boot JUnit中构造非空HttpSession的几种实用方案
首先得明确你是在做纯单元测试(不需要加载Spring上下文,只测方法逻辑)还是集成测试(需要Spring环境支持,比如依赖其他组件),两种场景的处理方式完全不同,我给你逐个拆解:
一、纯单元测试:用Mock框架模拟(最推荐)
如果只是想测试这个方法本身的逻辑,不需要依赖Spring容器,直接用Mockito模拟HttpSession就行——这样速度快,还能精准控制Session的行为,绝对不会出现NPE。
举个实际例子:假设你的待测试方法长这样
public class SessionValidator { public boolean isSessionValid(HttpSession session) { return session != null && "active".equals(session.getAttribute("userState")); } }
对应的JUnit测试代码可以这么写:
import org.junit.jupiter.api.Test; import org.mockito.Mockito; import jakarta.servlet.http.HttpSession; import static org.junit.jupiter.api.Assertions.*; class SessionValidatorTest { @Test void testValidSession() { // 1. 直接Mock出HttpSession对象 HttpSession mockSession = Mockito.mock(HttpSession.class); // 2. 设定调用getAttribute时的返回值 Mockito.when(mockSession.getAttribute("userState")).thenReturn("active"); SessionValidator validator = new SessionValidator(); // 3. 把Mock的Session传给方法测试 boolean result = validator.isSessionValid(mockSession); assertTrue(result); } @Test void testInvalidSession() { HttpSession mockSession = Mockito.mock(HttpSession.class); Mockito.when(mockSession.getAttribute("userState")).thenReturn("expired"); SessionValidator validator = new SessionValidator(); assertFalse(validator.isSessionValid(mockSession)); } }
Spring Boot Starter Test已经自带了Mockito,不需要额外加依赖,直接用就行。
二、集成测试:用Spring提供的MockHttpSession
如果你的方法依赖Spring的其他组件(比如Service、Repository),需要在Spring上下文里测试,那可以用Spring官方的MockHttpSession——这是专门为测试场景实现的HttpSession子类。
方式1:手动创建MockHttpSession
import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import jakarta.servlet.http.HttpSession; import org.springframework.mock.web.MockHttpSession; import static org.junit.jupiter.api.Assertions.*; @SpringBootTest class SessionValidatorIntegrationTest { @Autowired private SessionValidator sessionValidator; @Test void testSessionInSpringContext() { // 创建MockHttpSession实例,直接设置属性 HttpSession mockSession = new MockHttpSession(); mockSession.setAttribute("userState", "active"); boolean result = sessionValidator.isSessionValid(mockSession); assertTrue(result); } }
方式2:结合MockMvc模拟请求带Session
如果你的方法是Controller里的接口,需要模拟真实HTTP请求场景,可以通过MockMvc携带Session:
import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.mock.web.MockHttpSession; import org.springframework.test.web.servlet.MockMvc; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @WebMvcTest(YourController.class) class ControllerSessionTest { @Autowired private MockMvc mockMvc; @Test void testControllerWithValidSession() throws Exception { MockHttpSession session = new MockHttpSession(); session.setAttribute("userState", "active"); // 发送请求时带上这个Session mockMvc.perform(get("/api/check-session") .session(session)) .andExpect(status().isOk()); } }
为啥你之前会踩NPE坑?
大概率是这两种情况:
- 纯单元测试时直接传了null,或者没正确Mock Session就调用方法;
- 集成测试时想自动注入真实的HttpSession,但真实Session只有在HTTP请求上下文里才存在,测试环境默认不会自动生成,必须手动用Mock类创建。
记住:测试环境里不会凭空出现可用的HttpSession,必须手动模拟或者用Spring提供的Mock实现。
内容的提问来源于stack exchange,提问作者Josimar Lopes
相关产品推荐
相关产品推荐

