Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mockito how to verify lamba functions

I am trying to test following method:

public void execute(Publisher<T> publisher) throws Exception {
    PublishStrategy<T> publishStrategy = publisher.getPublishStrategy();
    publishStrategy.execute(publisher::executionHandler);
}

Following is the Junit code:

@Test
public void testExecute() throws Exception {
    PublishStrategy<Event> publishStrategy = Mockito.mock(PublishStrategy.class);
    Publisher<Event> publisher = Mockito.mock(Publisher.class);
    Mockito.when(publisher.getPublishStrategy()).thenReturn(publishStrategy);
    Mockito.doNothing().when(publishStrategy).execute(publisher::executionHandler);
    PublishJob job = new PublishJob(publisher);
    job.execute(publisher);
    Mockito.verify(publishStrategy, Mockito.times(1)).execute(publisher::executionHandler);
}

On the verify method call, I am getting following mockito exception:

Argument(s) are different! Wanted:
publishStrategy.execute(
    com.test.producer.jobs.PublishJobTest$$Lambda$3/1146825051@6f45df59
);
-> at com.test.producer.jobs.PublishJobTest.testExecute(PublishJobTest.java:23)
Actual invocation has different arguments:
publishStrategy.execute(
    com.producer.jobs.PublishJob$$Lambda$2/1525409936@38e79ae3
);
-> at com.producer.jobs.PublishJob.execute(PublishJob.java:30)

I don't understand why mockito considers both the lambda's are different?

Update I solved it without using Mockito.

Here's the other approach. Omitted empty overridden methods:

@Test
public void testExecute() throws Exception {
    PublishStrategy<Event> publishStrategy = new PublishStrategy<Event>() {
        @Override
        public void execute(Consumer<List<Event>> handler) {
            Assert.assertNotNull(handler);
        }
    };
    Publisher<Event> publisher = new AbstractPublisher<Event>() {
        @Override
        public void init(PublishStrategy<Event> publishStrategy) {
            this.publishStrategy = publishStrategy;
        }

        @Override
        public void executionHandler(List<IngestEvent> items) {

        }

        @Override
        public PublishStrategy<IngestEvent> getPublishStrategy() {
            return this.publishStrategy;
        }
    };
    publisher.init(publishStrategy);
    PublishJob job = new PublishJob();
    job.execute(publisher);
}
like image 822
Nilesh Barai Avatar asked Oct 27 '22 10:10

Nilesh Barai


1 Answers

In Java, two objects aren't equal because they are instances of the same class! Objects are equal because calling a.equals(b) returns true!

In your case, that class PublishJob probably doesn't override the equals method. So, comparing two lambda instances results in false. And note: I really don't see how you could fix this by adding an equals method.

In other words: when you do publisher::executionHandler you create two different lambda instances. It doesn't matter that they will both make a call on the same object. You have two lambda instances. And they are simply not equal. And that Mockito method checks for equality.

I think one way how to test this: see if you can get that lambda to be executed. Then verify that the expected call takes place on that object.

like image 100
GhostCat Avatar answered Nov 09 '22 14:11

GhostCat