使用Mockito测试R2dbc Repository时实例一直为null问题求助
问题根源&解决方案
核心错误点
- 链式打桩逻辑错误:Mockito不会自动为链式调用生成中间Mock对象,你直接对
userRepository.findAll().collectList().block()打桩时,userRepository.findAll()默认返回null,调用collectList()就会直接抛出空指针,根本执行不到block方法。 - 注解混用不兼容:
@RunWith(MockitoJUnitRunner.class)是JUnit4的注解,而@BeforeEach/@AfterEach是JUnit5的注解,两者共存会导致Mock初始化失效,Repository注入为null。 verify使用错误:verify只能校验Mock对象的方法调用,不能校验被测试类underTest自身的方法。
正确实现代码
不需要手动Mockblock方法,直接给Reactive Repository的返回值预设真实的Publisher对象即可,原生的Publisher的block方法会正常返回对应值:
// 用JUnit5的Mockito扩展,无需手动管理Mock生命周期 @ExtendWith(MockitoExtension.class) class UserTest { @InjectMocks private UserService underTest; @Mock private UserRepository userRepository; @Test void getApplicableUsers() { // 直接给findAll返回预设的Flux对象,后续collectList().block()自然返回空列表 when(userRepository.findAll()).thenReturn(Flux.empty()); // 若需要返回测试数据写法如下: // User testUser = new User(); // when(userRepository.findAll()).thenReturn(Flux.just(testUser)); Set<User> expected = underTest.getUsers(getUser(), getUsers()); // 校验repository的findAll方法被调用一次 verify(userRepository, times(1)).findAll(); } }
极端场景Mock block方法的示例(不推荐,仅作演示)
如果确实需要手动Mockblock方法,可以单独Mock中间的Flux/Mono对象:
@Mock private Flux<User> userFlux; @Mock private Mono<List<User>> listMono; // 打桩逻辑 when(userRepository.findAll()).thenReturn(userFlux); when(userFlux.collectList()).thenReturn(listMono); when(listMono.block()).thenReturn(new ArrayList<>());
内容的提问来源于stack exchange,提问作者Mike3355
相关产品推荐
相关产品推荐

