1

I'm fairly new to Mockito but I'm getting a NullPointerError when attempting to stub the Texture class. Here is my test:

import com.badlogic.gdx.graphics.Texture;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.junit.MockitoJUnitRunner;
import org.testng.annotations.BeforeMethod;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

@RunWith(MockitoJUnitRunner.class)
 class EntityTest {

     @InjectMocks
     public Texture mockedImg;

     @BeforeMethod
     public void setup() {
         mockedImg = mock(Texture.class);
         when(mockedImg.getWidth()).thenReturn(5);
         when(mockedImg.getHeight()).thenReturn(5);
     }

    @Test
    public void doesAnyOfMyCodeWork() {
         Assertions.assertEquals(mockedImg.getHeight(),5);
    }
}

And here is the error I'm getting:

java.lang.NullPointerException
    at EntityTest.doesAnyOfMyCodeWork(EntityTest.java:35) <19 internal calls>
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1540) <9 internal calls>
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1540) <18 internal calls>
    at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:69)
    at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
    at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)
    at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)

(line 35 is Assertions.assertEquals(mockedImg.getHeight(),5);)

Any help would be much appreciated!

PeteFL
  • 33
  • 6
  • What line is 35? – Kayaman Jan 12 '20 at 18:23
  • It's Assertions.assertEquals(mockedImg.getHeight(),5);, just edited in now. – PeteFL Jan 12 '20 at 18:28
  • Why do you have `@InjectMocks` on `mockedImg`, when you're manually mocking it, and you don't seem to have any mocks to inject into it? It should be either `@Mock` and no `mockedImg = mock(Texture.class);` line, or no annotation at all. See https://stackoverflow.com/questions/16467685/difference-between-mock-and-injectmocks – Kayaman Jan 12 '20 at 18:31
  • Just replaced InjectMocks with Mock and getting the same error sadly. – PeteFL Jan 12 '20 at 18:38
  • Then check if your `setup()` method is being run, and if `mockedImg` is `null` in your test method. – Kayaman Jan 12 '20 at 18:40
  • Your test is also completely useless. You didn't write `com.badlogic.gdx.graphics.Texture`, so you shouldn't be testing it. – Kayaman Jan 12 '20 at 18:53
  • Note: you shouldnt learn mockito by trial and error. Start by reading a good tutorial on Mockito. Learn from working examples. Dont just throw annotations into your code, without knowing what they **mean**. Anything you put into your source code you have to **understand** what it means. – GhostCat Jan 12 '20 at 19:01

3 Answers3

1

So I now have code that seems to work as the following:

import com.badlogic.gdx.graphics.Texture;
import org.junit.Before;
import org.junit.Test;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.ValueSource;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.junit.MockitoJUnitRunner;

import static org.mockito.Mockito.*;


@RunWith(MockitoJUnitRunner.class)
public class EntityTest {

     @Mock
     public Texture mockedImg;

     @Before
     public void setup() {
         mockedImg = mock(Texture.class);
         lenient().when(mockedImg.getWidth()).thenReturn(5);
         lenient().when(mockedImg.getHeight()).thenReturn(5);
     }


     @Test
     public void doesAnyOfMyCodeWork() {
         Assertions.assertEquals(mockedImg.getHeight(),5);
     }
}

Which is really odd as I had almost the exact same code yesterday and it was pulling up a whole load of errors (although I've moved my test to a different source folder which might have helped). Thanks for helping me out with this guys.

PeteFL
  • 33
  • 6
0

If you want to mock mockedImg you have to annotate it with @Mock. The @InjectMocks is used to inject mock fields into the tested object automatically.

So a possible solution to your problem would be the following

 class EntityTest {

     @Mock
     public Texture mockedImg;

     @BeforeMethod
     public void setup() {
         when(mockedImg.getWidth()).thenReturn(5);
         when(mockedImg.getHeight()).thenReturn(5);
     }

    @Test
    public void doesAnyOfMyCodeWork() {
         Assertions.assertEquals(mockedImg.getHeight(),5);
    }
}
Alexis Pavlidis
  • 1,080
  • 1
  • 11
  • 21
0

A simple way of testing without annotation:

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

class EntityTest
{
    @Test
    public void doesAnyOfMyCodeWork()
    {
        Texture mockedImg = mock(Texture.class);
        when(mockedImg.getWidth()).thenReturn(5);
        when(mockedImg.getHeight()).thenReturn(5);
        Assertions.assertEquals(mockedImg.getHeight(), 5);
    }
}
fabfas
  • 2,200
  • 1
  • 21
  • 21
  • It works when doing that, I've switched to lenient mocking in the @Before function (and edited a few other things) and it seems to work now. Thanks! – PeteFL Jan 13 '20 at 11:53