Mockito.doNothing() keeps returning null pointer exception

I know I should not be testing void methods like this, but I am just testing Mockito.doNothing() as of now with a simple example.

My Service class:

@Service
public class Service{ @Autowired private Consumer<String, String> kafkaConsumer; public void clearSubscribtions(){ kafkaConsumer.unsubscribe(); }
}

My Test class:

 @MockBean private Consumer<String, String> kafkaConsumer; @Test public void testClearSubscriptions() { Service service = new Service(); Mockito.doNothing().when(kafkaConsumer).unsubscribe(); service.clearSubscriptions(); }

The test keeps failing with a null pointer exception. When I debugged it, it goes into the clearSubscription method of the service class, and there on the line of kafkaConsumer.unsubscribe(), kafkaConsumer is null. But I mocked the consumer, why is it throwing null pointer exception and I should be skipping over that method, right?

Edit: All the declarations of the class:

@Autowired private Consumer<String, String> kafkaConsumer; @Autowired private Service2 service2; private final Object lock = new Object(); private static Logger logger = LoggerFactory.getLogger(Service.class); private HashMap<String, String> subscribedTopics = new HashMap<>();

Figured out what was wrong, I needed to auto wire the service

1

1 Answer

You are instantiating a new service Service service = new Service(); but from what I can see you are never injecting the mock bean into the new service.

Here is a sample of what I think you could do if you are using mockito only and dont need to instantiate a spring container (used a single class for ease of example dont do this in actual code):

package com.sbp;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.runners.MockitoJUnitRunner;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@RunWith(MockitoJUnitRunner.class) // run with mockitos runner so annotations are processed
public class MyServiceTest { public interface Consumer<T, R> { public void unsubscribe(); } @Service public class KafkaConsumer implements Consumer<String, String> { @Override public void unsubscribe() { } } @Service public class MyService { @Autowired private Consumer<String, String> kafkaConsumer; public void clearSubscriptions() { kafkaConsumer.unsubscribe(); } } @Mock // tell mockito that this is a mock class - it will instantiate for you private Consumer<String, String> kafkaConsumer; @InjectMocks // tell mockito to inject the above mock into the class under test private MyService service = new MyService(); @Test public void testClearSubscriptions() { service.clearSubscriptions(); Mockito.verify(kafkaConsumer, Mockito.times(1)).unsubscribe(); }
}

If you need an example via Spring using MockBean or without and dependencies, let me know and I can post.

UPDATED: adding sample using spring junit runner and using spring boot's mockbean annotation

package com.sbp;
import com.sbp.MyServiceTest.TestContext.MyService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Service;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class) // run with spring
@SpringBootTest(classes = MyServiceTest.TestContext.class) // make it a spring boot test so @MockBean annotation is processed, provide a dummy test context class
public class MyServiceTest { public interface Consumer<T, R> { public void unsubscribe(); } @Configuration public static class TestContext { @Service public class KafkaConsumer implements Consumer<String, String> { @Override public void unsubscribe() { } } @Service public class MyService { @Autowired private Consumer<String, String> kafkaConsumer; public void clearSubscriptions() { kafkaConsumer.unsubscribe(); } } } @MockBean // this will create a mockito bean and put it in the application context in place of the Kafka consumer bean defined in the TestContext class private Consumer<String, String> kafkaConsumer; @Autowired // inject the bean from the application context that is wired with the mock bean private MyService myService; @Test public void testClearSubscriptions() { myService.clearSubscriptions(); Mockito.verify(kafkaConsumer, Mockito.times(1)).unsubscribe(); }
}
6

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like