如何Mock HttpSession并传递给依赖session的方法?测试时属性为null
测试带HttpSession参数方法的问题排查与修复
现有测试代码的核心错误
- 注解配置误用:
@InjectMocks是Mockito用于标记被测对象的注解,功能是将容器中所有匹配类型的@Mock实例自动注入到被测对象的依赖字段中。将该注解打在MockHttpSession上属于完全错配,会导致Mockito生成一个没有任何内存存储逻辑的代理对象,所有调用的setAttribute、getAttribute方法都走Mockito默认空实现,完全无法存储或读取属性值。 - 键值匹配错误:业务方法从session中读取的属性键为
"currentUserUsername",对应存储值是字符串类型的用户名;但测试代码中设置的属性键为"luboslav"、值是整个User对象,键名与业务逻辑读取的键完全不一致,哪怕session正常存储属性,读取目标键时也必然返回null。 - 测试对象选型错误:
org.springframework.mock.web.MockHttpSession本身是Spring Test模块提供的、基于内存Map实现的HttpSession专用测试类,本身可直接实例化使用,完全不需要通过Mockito做代理mock。
修正后的完整测试实现
@ExtendWith(MockitoExtension.class) public class LoginServiceMvcTests { @Mock UserRepository mockUserRepository; @Mock UserService mockUserService; // 移除错误的@InjectMocks标注,使用Spring内置内存实现 private MockHttpSession mockHttpSession; // 仅给被测对象标注@InjectMocks,Mockito会自动完成依赖注入 @InjectMocks LoginServiceMvc loginService; private User junkie; private User organizer; @BeforeEach public void setup() { junkie = Helpers.createJunkie(); organizer = Helpers.createOrganizer(); // 每个测试用例初始化独立的session实例,避免测试间状态污染 mockHttpSession = new MockHttpSession(); } @Test public void tryGetUser_Should_GetUserFromSession_When_UserIsLogged() { // Arrange:与业务方法的属性键、值类型完全对齐 String testUsername = "luboslav"; mockHttpSession.setAttribute("currentUserUsername", testUsername); Mockito.when(mockUserService.getByUsername(testUsername)) .thenReturn(junkie); // Act User result = loginService.tryGetUser(mockHttpSession); // Assert Mockito.verify(mockUserService, Mockito.times(1)) .getByUsername(testUsername); assertEquals(junkie, result); } }
常见补充说明
- 如果确实需要通过Mockito原生mock
HttpSession接口(而非使用Spring提供的MockHttpSession实现),必须手动桩定getAttribute方法的返回值,否则默认返回null:// 原生Mockito mock HttpSession的标准写法 HttpSession mockSession = Mockito.mock(HttpSession.class); Mockito.when(mockSession.getAttribute("currentUserUsername")).thenReturn("luboslav"); - 注意区分两类session测试对象的差异:Spring提供的
MockHttpSession是有实际存储逻辑的真实实现类;@Mock生成的代理对象默认所有方法无逻辑、返回null,两者行为完全不同,不可混用。
内容的提问来源于stack exchange,提问作者oneofakind
相关产品推荐
相关产品推荐

