133

I try to run this test:

    @Mock IRoutingObjHttpClient routingClientMock;
    @Mock IRoutingResponseRepository routingResponseRepositoryMock;


    @Test
    public void testSendRoutingRequest() throws Exception {
        CompleteRoutingResponse completeRoutingResponse = new CompleteRoutingResponse();
        completeRoutingResponse.regression_latencyMillis = 500L;

        Mockito.when(routingClientMock.sendRoutingRequest(any(RoutingRequest.class))).thenReturn(completeRoutingResponse);

        RoutingObjHttpClientWithReRun routingObjHttpClientWithReRun = new RoutingObjHttpClientWithReRun
                (routingClientMock, routingResponseRepositoryMock);

...
    }

but I get NullPointerException for:

Mockito.when(routingClientMock.

what am i missing?

Elad Benda2
  • 13,852
  • 29
  • 82
  • 157
  • 11
    Do you call `MockitoAnnotations.initMocks(this)`? (Should probably be in @Before method) Or, do you have any other @Rule which you expect to initialize your mocks? (It isn't automagic) – Andy Turner Apr 12 '15 at 14:43
  • 1
    You need to instantiate the `routingClientMock` e.g. `routingClientMock = Mockito.mock(RoutingObjHtttpClient.class);` – Tim Biegeleisen Apr 12 '15 at 14:48
  • You could also use `@RunWith(MockitoJUnitRunner.class)` at your class – Roland Weisleder Apr 12 '15 at 14:51
  • please write as an answer and I'll mark it – Elad Benda2 Apr 12 '15 at 14:52
  • In my case (not the case for this question), I was trying to mock a dependency for another Mock for the UUT (i.e. two layers of mocks). This does not work trivially, and so the second layer mock was null. – zr0gravity7 Dec 19 '22 at 17:48

19 Answers19

138

When you want to use the @Mock annotation you should use the MockitoJUnitRunner

@RunWith(MockitoJUnitRunner.class)
public class MockitoTest {

    @Mock
    private IRoutingObjHttpClient routingClientMock;

    @Test
    public void testSendRoutingRequest() throws Exception {
        // ...
    }

}

See also this tutorial.

Roland Weisleder
  • 9,668
  • 7
  • 37
  • 59
81

Same problem can occur if you are using Junit5 since there is no more '@RunWith' annotation.

In this case you should annotate your class with:

@ExtendWith(MockitoExtension.class)
public class MyTestClass {
...

You should also import into your dependency (Maven - pom.xml):

<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-junit-jupiter</artifactId>
    <version>${mockito.version}</version>
    <scope>test</scope>
</dependency>
Gjera
  • 1,117
  • 9
  • 7
73

You have three options for activating the @Mock annotation: MockitoRule, MockitoJUnitRunner, MockitoAnnotations.initMocks(this). IMHO using the MockitoRule is the best one, because it lets you still choose another runner like e.g. Parameterized.

Use the MockitoRule

public class MockitoTest {

  @Mock
  private IRoutingObjHttpClient routingClientMock;

  @Rule
  public MockitoRule rule = MockitoJUnit.rule();

  @Test
  public void testSendRoutingRequest() throws Exception {
    // ...
  }
}

Use the MockitoJUnitRunner

@RunWith(MockitoJUnitRunner.class)
public class MockitoTest {

  @Mock
  private IRoutingObjHttpClient routingClientMock;

  @Test
  public void testSendRoutingRequest() throws Exception {
    // ...
  }
}

Call MockitoAnnotations.initMocks(this) explicitly.

This can be done in qn @Before method, in your own runner or in an own rule.

public class MockitoTest {

  @Mock
  private IRoutingObjHttpClient routingClientMock;

  @Before
  public void createMocks() {
    MockitoAnnotations.initMocks(this);
  }

  @Test
  public void testSendRoutingRequest() throws Exception {
    // ...
  }
}
M. Twarog
  • 2,418
  • 3
  • 21
  • 39
Stefan Birkner
  • 24,059
  • 12
  • 57
  • 72
  • 1
    In most of the test classes @RunWith(MockitoJUnitRunner.class) works fine in injecting mocks. But in few test classes both @RunWith(MockitoJUnitRunner.class) and MockitoAnnotations.initMocks(this) worked together only. Is there any explaination for this issue ? – Nakul Goyal Aug 18 '20 at 19:10
  • Can you please create another question on StackOverflow with a complete example. – Stefan Birkner Aug 27 '20 at 21:13
33

If you use junit.jupiter with @ExtendWith(MockitoExtension.class) for test class but mocks are null, ensure that @Test annotation is imported from

import org.junit.jupiter.api.Test;

instead of org.junit.Test;

Rammgarot
  • 1,467
  • 14
  • 9
11

What solved this issue for me (combination of answers above and my own additions):

  • MockitoAnnotations.initMocks(this); in the @Before method
  • Test class must be public
  • Test methods must be public
  • import org.junit.Test; instead of import org.junit.jupiter.api.Test;

When doing command + N --> Test... in Intellij it generates (as a default at least) some boilerplate that did not work in my case.

amanatee
  • 191
  • 2
  • 4
  • 2
    Thank you so much you saved me. My issue was the last one you commented on. Much love! – Mohamed Ali Jan 01 '21 at 19:29
  • 1
    My scenario includes `@RunWith(PowerMockRunner.class)` and `@PowerMockRunnerDelegate(Parameterized.class)`. For each param declared under `@Parameterized.Parameters` the `@Before` annotations invokes some mocked objects `null`. Without parameters, tests run fine, no NPE. With parameteres, needed `MockitoAnnotations.initMocks(this)`. Thanks! – Junio Nov 01 '21 at 11:04
  • For some reason, my IDE was importing org.testng.annotations.Test by default. I had to change it to org.junit.Test and it worked. – R11G Apr 15 '23 at 16:38
8

For me, even after adding @RunWith(MockitoJUnitRunner.class) it was not working.
Turned out, I had made the silly mistake of importing @Test from

import org.junit.jupiter.api.Test;

instead of

import org.junit.Test;

After correcting it, it worked!

Ganesh Satpute
  • 3,664
  • 6
  • 41
  • 78
5

Add @ExtendWith(MockitoExtension.class) annotation to the test class and it should work given You are using Junit 5+ version. If you are using older version of Junit use @RunWith(MockitoJUnitRunner.class) annotation.

Adarsh
  • 79
  • 1
  • 2
4
  1. You should use @RunWith(SpringJUnit4ClassRunner.class) at your class
  2. You have to call MockitoAnnotations.initMocks(this); in @Before method
enoder
  • 91
  • 5
  • 4
    why `@RunWith(SpringJUnit4ClassRunner.class)` and not `MockitoJUnitRunner.class` ? – Elad Benda2 Apr 12 '15 at 21:08
  • 1
    You don't need SpringJUnit4ClassRunner unless you want to wire in some Spring context into your test - which is a very twisty passage of its own. – David Victor Nov 04 '19 at 14:01
4

It can also be an import problem, so make sure you have the appropriate imported package.

For example, the "org.easymock" package also does have an annotation called @Mock, which of course, won't work with Mockito specific setup.

Oliver
  • 1,218
  • 1
  • 17
  • 21
3

I had the problem that I declared @Mock MyClass myClass and then tried to mock a behaviour inside my @BeforeAll annotated method:

@Mock
private MyClass myClass;

...

@BeforeAll
public void init()
{
    ...
    Mockito.when(myClass.something()).thenReturn("Not found")
    ...
}

Apparently init() was executed before the mock initialization of myClass, so myClass == null inside init().

The solution was to change the annotation from @BeforeAll to @BeforeEach.

grandmaximum
  • 121
  • 2
  • 4
2

For me it worked when I added :

  1. At class level:
@RunWith(MockitoJUnitRunner.class).
  1. Inside class:
@Before
      public void createMocks() {
        MockitoAnnotations.initMocks(this);
      }
Joundill
  • 6,828
  • 12
  • 36
  • 50
1

Try to to check if the method that you are calling is a final method or not.

Mockito cannot mock the final method. https://github.com/mockito/mockito/wiki/FAQ

UmAnusorn
  • 10,420
  • 10
  • 72
  • 100
1

Junit 5 with InjectMocks. Based on above suggestion https://stackoverflow.com/a/55616702/2643815

 @ExtendWith(MockitoExtension.class)
public class MyClientTest {
@Mock
    Environment environment;
    @Mock
    ClassCreator classCreator;

    @InjectMocks
    MyClient myClient;


    @Test
    public void mytest() {
            myClient = new MyClient(environment, classCreator);
            
            }
            }
Smart Coder
  • 1,435
  • 19
  • 19
0

For me adding the annotation to the class:

@RunWith(MockitoJUnitRunner.class)

and modifying the version of Mockito solved this issue.

<dependency>
        <groupId>org.mockito</groupId>
        <artifactId>mockito-core</artifactId>
        <version>2.23.4</version>
        <scope>test</scope>
</dependency>
Suhas Karanth
  • 57
  • 3
  • 7
0

I had the same issue, but I found updating my tests (which were originally written for JUnit 3 and used the legacy setUp() and tearDown() methods) to JUnit 4 and modern annotated fixture methods worked.

Additionally, if you're using the Rule:

@Rule public MockitoRule rule = MockitoJUnit.rule();

Make sure the rule is also on a public class or you will receive the message:

How did getFields return a field we couldn't access?
Dan Gravell
  • 7,855
  • 7
  • 41
  • 64
0

Found this solution in comments that worked for me. Do this for all the mocks you are creating.

You need to instantiate the routingClientMock e.g.

routingClientMock = Mockito.mock(RoutingObjHtttpClient.class);
Aditya
  • 13
  • 5
0

My issue was that I was trying to mock an object which was final in my service. Just needed to remove final and it worked.

Adriaan
  • 17,741
  • 7
  • 42
  • 75
  • 1
    Thank you for answering! However, questions do not belong in answers, which is why I've removed it. You can [ask a new question](https://stackoverflow.com/questions/ask), leaving a link to this post, if you'd like. – Adriaan Jul 18 '22 at 12:05
0

our application uses JUNIT5 , same issue occured. I replaced @Mock with @InjectMocks - then issue was resolved

F0cus
  • 585
  • 3
  • 18
  • 52
-4

If you are also using PowerMock then

@RunWith(MockitoJUnitRunner.class)

can be replaced with

@RunWith(PowerMockRunner.class)

This will activate your @Mocks and enable the PowerMock functionality.

dur
  • 15,689
  • 25
  • 79
  • 125
sam
  • 123
  • 1
  • 11