Spring Boot服务方法单元测试问题:JUnit 5+Mockito测试失败
解决JUnit 5 + Mockito测试Spring Boot服务方法的问题
问题根源分析
报错核心原因是你尝试对非Mock对象调用when()存根方法:when(numberValue.length()).thenReturn(eq(16));。numberValue是普通String实例,并非Mockito创建的代理对象,Mockito只能Mock被它管控的对象方法。此外还有两处存根逻辑错误:
thenReturn(any())是错误用法:any()是参数匹配器,不能作为返回值使用,必须返回具体实例或确定值。- 若MyUtils/MyMapper仍存在静态调用逻辑,即使改成实例方法,也要确保服务类通过依赖注入使用实例,而非直接调用静态方法。
具体修复步骤
1. 移除无效的String方法存根
直接删掉when(numberValue.length()).thenReturn(eq(16));,你传入的numberValue本身就是16位字符串,filter条件会自动满足,完全不需要Mock。
2. 调整服务类的依赖注入方式
修改服务类,通过构造器注入MyUtils和MyMapper实例,替代原有的静态调用逻辑:
@Service public class MyService { private final MyUtils myUtils; private final MyMapper myMapper; // 构造器注入(Spring推荐方式) public MyService(MyUtils myUtils, MyMapper myMapper) { this.myUtils = myUtils; this.myMapper = myMapper; } public Maybe<MyResponse> generate(String numberValue) { return Maybe.just(numberValue) .filter(number -> number.length() == Constants.REQUEST_REQUIRED) .flatMap(number -> myUtils.generate()) // 使用注入的实例调用方法 .map(myMapper::createResponse) // 使用注入实例的方法引用 .switchIfEmpty(Maybe.error(MyExceptioManager.throwException400(...))); } }
3. 修正测试类的Mock逻辑
测试类中正确Mock依赖并配置合法的存根规则:
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import reactor.core.publisher.Maybe; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.when; @ExtendWith(MockitoExtension.class) // 启用JUnit 5的Mockito支持 class MyServiceTest { @Mock private MyUtils myUtils; // Mock MyUtils实例 @Mock private MyMapper myMapper; // Mock MyMapper实例 @InjectMocks private MyService myService; // 将Mock自动注入到被测服务 @Test void generate() { String numberValue = "1234567891234567"; String mockGenerateResult = "模拟生成的字符串"; MyResponse expectedResponse = new MyResponse("1234"); // 存根MyUtils的generate方法,返回符合类型的Maybe对象 when(myUtils.generate()).thenReturn(Maybe.just(mockGenerateResult)); // 存根MyMapper的createResponse方法,返回预期的MyResponse实例 when(myMapper.createResponse(anyString())).thenReturn(expectedResponse); myService.generate(numberValue) .test() .assertNoErrors() .assertComplete() .assertValue(response -> response.getCode().equals("1234")); } }
关键注意事项
- 若
MyUtils.generate()返回Maybe类型,存根时必须返回Maybe.just(...),要严格匹配方法的返回值类型。 thenReturn()必须传入具体对象或确定值,any()这类匹配器仅能用于when()的方法参数中。- 测试类必须添加
@ExtendWith(MockitoExtension.class),否则Mockito无法识别@Mock和@InjectMocks注解。
内容的提问来源于stack exchange,提问作者DarkVaderM
相关产品推荐
相关产品推荐

