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 Mono
s or Optional
s or CompletableFuture
s almost always leads to problems (I have also seen real test code which created and set up mocks for List
s and Map
s). 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:
- You mock the method that you are verifying
- Your mocked mono is successful and failed at the same time
- You are never calling a method on your class under test
- 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.