2

Trying to write the unit test using Mockito for the below code, but I'm getting misusing method exception. Result is not null, verified, entering into loop as well.

if(Result!=null) {
   result.getRecordMetadata().topic()
}

This is what I have written:

@Mock
private SendResult<String, data> sendResultData;

RecordMetadata recordMetadata = new RecordMetadata(new TopicPartition("topic", 0), 0, 0, 1234567890L, 1234567890L, 1024, 1024);

SendResult<String, Data> result = new SendResult<String, Data>(producerRecord, recordMetadata);

when(recordMetadata.topic()).thenReturn("topic");

when(sendResultData.getRecordMetadata()).thenReturn(recordMetadata);

Exception:

org.mockito.exceptions.misusing.MissingMethodInvocationException:
when() requires an argument which has to be 'a method call on a mock'.
For example:
when(mock.getArticles()).thenReturn(articles);

Also, this error might show up because:

you stub either of: final/private/equals()/hashCode() methods.
Those methods cannot be stubbed/verified.
Mocking methods declared on non-public parent classes is not supported.

inside when() you don't call method on mock but on some other object.

at XXXXX.test(Test.java:172)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
Amani
  • 21
  • 1
  • 7

2 Answers2

2

Mockito is not able to mock/spy final classes. RecordMetadata is a final class.

What you can do instead is : Since

Future<RecordMetadata>

is returned when you do a send on kafka.

  1. Mock what is returned (the result future)

Future future = Mockito.mock(Future.class);

  1. Create/instantiate a dummy RecordMetadata as follows
    TopicPartition topicPartition = new TopicPartition("test",1);  RecordMetadata metadata = 
        new RecordMetadata(topicPartition, 0,0,0,Long.valueOf(0),0, 0);
  1. And then whenever you do a get on your returned result future (step 1), make the mocked future return the dummy recordMetadata you created in step 2.

when(future.get()).thenReturn(metadata);

mykey
  • 1,943
  • 19
  • 13
0

I don't see you mock recordMetadata anywhere in your example. You can not mock a method of an object which is not a mock or spied.

You should either provide a mock with annotations:

@Mock
private RecordMetadata recordMetadata;

or simply:

RecordMetadata recordMetadata = Mockito.mock(RecordMetadata.class);

Also, @mock annotation should be @Mock

Pavel Smirnov
  • 4,611
  • 3
  • 18
  • 28
  • Thanks for the info, I tried both of them. I still an exception ```org.mockito.exceptions.base.MockitoException: Cannot mock/spy class org.apache.kafka.clients.producer.RecordMetadata Mockito cannot mock/spy because : - final class at XXX.Test(Test.java:170) – Amani Apr 17 '19 at 16:13
  • 1
    @Amani, you have to use Mockito 2 in order to mock final classes and configure it properly. Have a look at this answer: https://stackoverflow.com/questions/40979402/mock-final-class-with-mockito-2 – Pavel Smirnov Apr 17 '19 at 16:58