Home > Software design >  Mock consumers interface in subscribe method
Mock consumers interface in subscribe method

Time:09-26

I am trying to mock two consumer interfaces inside subscribe method

ConsumerService.java

  @Autowired
  ConsumerDao consumerDao;
  
  public void insertStatus(){
  
  SchedularStatus schedularStatus = new SchedularStatus();
  Mono<Object> savedConsumer =  consumerDao.save(schedularStatus);
  savedConsumer.subscribe(success -> Log.info("consumer data saved")),
            (error-> Log.error("Error while saving schedular data));" 
}

Below Junit test code I have tried

ConsumerServiceTest.java

@ExtendWith(MockitoExtension.class)
class ConsumerServiceTest {
 
@InjectMock
ConsumerService consumerService;

@Mock
Mono<Object> mono;

@Mock
ConsumerDao consumerDao;

@Test
void testInsertStatus(){

Mockito.when(consumerDao.save(any(SchedularStatus))).thenReturn(mono);
doAnswer(answer -> {
  Consumer<Object> consumer1 = answer.getArgument(0);
  Consumer<Object> consumer2 = answer.getArgument(1);
  consumer1.accept(new Object());
  consumer2.accept(new Object());
  return null;
    }).when(mono).subscribe(any(Consumer.class), any(Consumer.class));
  Mockto.verify(consumerDao).save(any(SchedularStatus.class));
}

But I am getting Nullpointer Exception

java.lang.NullPointerException : errorConsumer
    at java.util.Objects.requireNonNull(Ojbects.java:228)
    at reactor.core.publisher.Mono.subscribe(Mono.java:4278)

CodePudding user response:

Don't mock non-service classes. Mocking Monos or Optionals or CompletableFutures almost always leads to problems (I have also seen real test code which created and set up mocks for Lists and Maps). Simply return a real instance:

Mockito.when(consumerDao.save(any(SchedularStatus)))
        .thenAnswer(a -> Mono.just(new Object()));

And a second test which sets up the mock to return a failed Mono (Mono.error(new Exception())).

But then again, your test is not really testing anything (or performing very questionable actions), because:

  1. You mock the method that you are verifying
  2. Your mocked mono is successful and failed at the same time
  3. You are never calling a method on your class under test
  4. Your consumers don't do anything really, so why bother calling them?

CodePudding user response:

Your NPE comes from your mock configuration :

doAnswer(answer -> {
  Consumer<Object> consumer1 = answer.getArgument(0);
  Consumer<Object> consumer2 = answer.getArgument(1);
  consumer1.accept(new Object());
  consumer2.accept(new Object());
  return null; // You return null instead of a valid Disposable
    }).when(mono).subscribe(any(Consumer.class), any(Consumer.class));

subscribe method return a Disposable. You have to provide one.

  • Related