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

如何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原生mockHttpSession接口(而非使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.27 00:54:04