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

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

Chloe Bennett

Chloe Bennett

Culture, Media & Entertainment Columnist

Chloe Bennett explores the intersection of pop culture, streaming entertainment, digital trends, and contemporary lifestyle. Her weekly commentary reaches thousands of culture enthusiasts.

Share this article
Twitter Facebook Pinterest