Spring/Mockito中mock findByPrincipalName方法遇类型错误的解决办法
问题分析与解决方案
错误原因
这个编译错误是泛型通配符不匹配导致的:
- 你声明的
sessionRepository是FindByIndexNameSessionRepository<?>,Mockito会推断findByPrincipalName的返回类型为Map<String, ?> - 但你传入的
sessions是Map<String, ? extends Session>,两者的通配符捕获类型属于不同的匿名类型(capture#2和capture#3),编译器无法认定它们兼容。
正确Mock方法
方案1:调整Repository泛型声明
将sessionRepository的泛型改为带上限的通配符,让返回类型与你的sessions匹配:
Map<String, ? extends Session> sessions = new HashMap<>(); @MockBean private FindByIndexNameSessionRepository<? extends Session> sessionRepository; when(this.sessionRepository.findByPrincipalName(VALID_SUB)).thenReturn(sessions);
方案2:用doReturn绕过类型检查
如果无法修改Repository的泛型声明,使用Mockito的doReturn语法,它不会在编译阶段做严格的类型校验:
Map<String, ? extends Session> sessions = new HashMap<>(); @MockBean private FindByIndexNameSessionRepository<?> sessionRepository; doReturn(sessions).when(this.sessionRepository).findByPrincipalName(VALID_SUB);
方案3:强制类型转换
通过强制转换让编译器认可类型兼容:
Map<String, ? extends Session> sessions = new HashMap<>(); @MockBean private FindByIndexNameSessionRepository<?> sessionRepository; when(this.sessionRepository.findByPrincipalName(VALID_SUB)) .thenReturn((Map<String, ?>) sessions);
关于RedisSession不可访问的问题
你不需要创建RedisSession实例,直接MockSession接口即可:
// Mock一个Session对象 Session mockSession = Mockito.mock(Session.class); // 按需MockSession的方法,比如getId() when(mockSession.getId()).thenReturn("test-session-id"); Map<String, ? extends Session> sessions = new HashMap<>(); sessions.put("test-session-id", mockSession);
内容的提问来源于stack exchange,提问作者berimbolo
相关产品推荐
相关产品推荐

