测试时Password Encoder出现NullPointerException问题求助
问题排查与解决方案
核心原因
你遇到的NullPointerException本质是:Mock的WebConfig实例的passwordEncoder()方法未被正确Stub,调用时返回null,导致后续链式调用encode()方法触发空指针。以下是具体排查方向和解决方法:
1. 检查WebConfig.passwordEncoder()方法的修饰符
Mockito无法Mock静态方法或final方法,如果你该方法是这两种类型之一,Mock会失效:
- 如果是静态方法:将其改为实例方法(Spring配置类中的Bean方法通常是实例方法,除非你误用了static)。
- 如果是final方法:
- 方案一:修改方法为非final。
- 方案二:开启Mockito对final方法的支持:添加
mockito-inline依赖,或在src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker文件中写入mock-maker-inline。
2. 修正Stub语句的写法
你当前的链式Stub写法when(webConfig.passwordEncoder().encode(any())).thenReturn(...)会先执行webConfig.passwordEncoder(),此时该方法返回null,直接触发NPE。正确的做法是先StubpasswordEncoder()返回Mock的编码器,再Stub编码器的encode()方法:
// 1. Mock BCryptPasswordEncoder实例 BCryptPasswordEncoder mockPasswordEncoder = Mockito.mock(BCryptPasswordEncoder.class); // 2. 让WebConfig的passwordEncoder()返回这个Mock实例 when(webConfig.passwordEncoder()).thenReturn(mockPasswordEncoder); // 3. 再Stub编码器的encode方法 when(mockPasswordEncoder.encode(any(CharSequence.class))).thenReturn(userUpdated.getPassword());
3. 确认Mock实例的注入正确性
确保你的UserService依赖的WebConfig是你Mock的实例,而非Spring上下文的真实实例:
- 测试类上添加
@ExtendWith(MockitoExtension.class)(JUnit 5)或@RunWith(MockitoJUnitRunner.class)(JUnit 4),让Mockito管理Mock对象。 - 使用
@Mock注解创建WebConfig实例,并用@InjectMocks注入到UserService中:@ExtendWith(MockitoExtension.class) class UserServiceTest { @Mock private WebConfig webConfig; @InjectMocks private UserService userService; // 测试方法... }
4. 验证Stub是否生效
在Stub语句后添加打印语句,确认webConfig.passwordEncoder()返回的不是null:
System.out.println(webConfig.passwordEncoder()); // 输出应为Mock实例的地址,而非null
内容的提问来源于stack exchange,提问作者person
相关产品推荐
相关产品推荐

