简体   繁体   中英

How to mock method in Mono.flatMap()?

I write unit tests for some service and I don't understand, why some method that i mock don't call. I try to test testDeleteDeviceWhenDeviceNotFound() method and it's pass, but when I try testDeleteDeviceSuccess() I have problems

@Service
@Slf4j
@AllArgsConstructor
public class DeviceService {

    private DeviceRepository deviceRepository;
    private SyncSender syncSender;

    public Mono<Void> deleteDevice(long deviceId) {
        return deviceRepository
                .findById(deviceId)
                .switchIfEmpty(Mono.error(new NotFoundException()))
                .flatMap(existingDevice -> deviceRepository
                        .delete(existingDevice)
                        .then(syncSender.sendDeviceDelete(existingDevice.getDeviceId()))
                );
    }

} and myTest

   @ExtendWith(MockitoExtension.class)
class DeviceServiceTest {
    @Mock
    private DeviceRepository deviceRepository;
    @Mock
    private SyncSender syncSender;
    @InjectMocks
    private DeviceService deviceService;

    @Test
@DisplayName("Test deleteDevice when NotFoundException")
void testDeleteDeviceWhenDeviceNotFound() {
    long deviceId = 100L;
    Mockito.when(deviceRepository.findById(deviceId)).thenReturn(Mono.empty());
    Mono<Void> mono = deviceService.deleteDevice(deviceId);
    StepVerifier
            .create(mono)
            .expectErrorMatches(throwable -> throwable instanceof NotFoundException)
            .verify();
}
    @Test
    @DisplayName("Test deleteDevice success")
    void testDeleteDeviceSuccess() {
        DeviceModel deviceModel = createDeviceModel();
        deviceModel.setDeviceId(100L);
        Mockito.when(deviceRepository.findById(deviceModel.getDeviceId())).thenReturn(Mono.just(deviceModel));
        Mockito.when(syncSender.sendDeviceDelete(anyLong())).thenReturn(Mono.empty());
        Mockito.when(deviceRepository.delete(any(DeviceModel.class))).thenReturn(Mono.empty());
        deviceService.deleteDevice(deviceModel.getDeviceId());

    }
}

Exceptions from junit that one of the stubbed methods were never realized in the code under test, during test execution

    org.mockito.exceptions.misusing.UnnecessaryStubbingException: 
Unnecessary stubbings detected.
Clean & maintainable test code requires zero unnecessary code.
Following stubbings are unnecessary (click to navigate to relevant line of code):
  1. -> at com.ecosoft.dms.device.vending.service.DeviceServiceTest.testDeleteDeviceSuccess(DeviceServiceTest.java:172)
  2. -> at com.ecosoft.dms.device.vending.service.DeviceServiceTest.testDeleteDeviceSuccess(DeviceServiceTest.java:173)
Please remove unnecessary stubbings or use 'lenient' strictness. More info: javadoc for UnnecessaryStubbingException class.

And when I try debug mode I see that I return on this step.Why?

.flatMap(existingDevice -> deviceRepository

In your failing test, you have:

deviceService.deleteDevice(deviceModel.getDeviceId());

This creates a mono, but never launches underlying async tasks. The test finishes, and Mockito correctly reports that stubbed methods were never called.

You used a StepVerifier in your other test, to my eyes you need to use it here as well to trigger underlying async operations

StepVerifier.create(deviceService.deleteDevice(deviceModel.getDeviceId()))
            .verifyComplete();

Check simpler examples:

@Test
void testMonoNotRun() {
    Mono.fromCallable(() -> {
        System.out.println("Callable run");
        return 1;
    });
}

@Test
void testMonoRunBySubscribe() {
    Mono.fromCallable(() -> {
        System.out.println("Callable run");
        return 1;
    }).subscribe();
}

@Test
void testMonoRunByStepVerify() {
    StepVerifier.create(Mono.fromCallable(() -> {
        System.out.println("Callable run");
        return 1;
    })).verifyComplete();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM