Jungle
Jungle

Reputation: 107

Mock object throws NPE

i going to create mockito test for my service layer, I give an example one of class this layer below

 @Service
public class LangServiceImpl implements LangService {
    @Autowired
    private LangDaoImpl langDao;

    public LangDaoImpl getLangDao() {
        return langDao;
    }

    public void setLangDao(LangDaoImpl langDao) {
        this.langDao = langDao;
    }

    ...
}

When i was running my test, i got this NPE

java.lang.NullPointerException
    at com.phonebook.service.LangServiceTest.getByIdTest(LangServiceTest.java:38)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.mockito.internal.runners.JUnit45AndHigherRunnerImpl.run(JUnit45AndHigherRunnerImpl.java:37)
    at org.mockito.runners.MockitoJUnitRunner.run(MockitoJUnitRunner.java:62)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:234)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:74)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)

I wrote this test

 @RunWith(MockitoJUnitRunner.class)
    public class LangServiceTest {
        private static final Logger LOG = Logger.getLogger(AddressDao.class);
        private final String COUNTRY_NAME = "Ukraine";

        @InjectMocks
        LangServiceImpl langService = new LangServiceImpl();

        @Mock
        LangDaoImpl langDao;

        @Before
        public void setUp() throws Exception {
            MockitoAnnotations.initMocks(this);
        }

        @Test
        public void getByIdTest(){
            try {
                when(langDao.findById(1).getLang()).thenReturn(COUNTRY_NAME);
                Assert.assertEquals(langService.findById(1).getLang(),COUNTRY_NAME);
            } catch (DataBaseException e) {
                LOG.error("Test not pass");
            }
        }
    }

so i try create mock object using this way LangDaoImpl mock = mock(LangDaoImpl.class); but result the same. Please help to solve the problem

Upvotes: 0

Views: 611

Answers (2)

Anton Dozortsev
Anton Dozortsev

Reputation: 4902

I just can assume that exception happen in this line:

when(langDao.findById(1).getLang()).thenReturn(COUNTRY_NAME);

Particularly in this place findById(1).getLang().

Solution first:

Use Answer#RETURNS_DEEP_STUBS on LangDaoImpl mock creation:

@Mock(answer = Answers.RETURNS_DEEP_STUBS)
LangDaoImpl langDao;

Solution second:

Change return value to entity with expected data.

when(langDao.findById(1)).thenReturn(new YourEntity(COUNTRY_NAME));

Upvotes: 0

Alexander
Alexander

Reputation: 2898

Your langDao.findById(1) returns null. First mock the value it returns:

Xxx xxx = mock(Xxx.class); //use your own class returned by the langDao
when(langDao.finById(1)).thenReturn(xxx);     

Also, use @Mock LangDao instead of @Mock LangDaoImpl.

Edit: one more thing: you don't have to use MockitoAnnotations.initMocks(...) if you use MockitoJUnitRunner.

Upvotes: 1

Related Questions