-1

I built a restful API with dropwizard. And now I want to test it with what dropwizard document provided.

public class BlogCommentResourceTest {
private static final BlogCommentDAO dao = mock(BlogCommentDAO.class);
private final BlogComment blogComment = new BlogComment(1, "url", "comment", new Date(), "name");
@ClassRule
public static final ResourceTestRule resources = ResourceTestRule.builder()
        .addResource(new BlogCommentResource(dao)).build();
List<BlogComment> list = new ArrayList<BlogComment>();

@Before
public void setUp(){
    list.add(blogComment);

    when(dao.getLast()).thenReturn(blogComment);
    when(dao.getAll(POJOs.BlogCommentPOJO.toString())).thenReturn(list);
}
@After
public void tearDown(){
    reset(dao);
}
@Test
public void getLast(){
    assertThat(resources.client().target("/blogcomments").request().get(List.class))
            .isEqualTo(list);
    verify(dao.getAll(POJOs.BlogCommentPOJO.toString()), times(1));
}

}

This is the method I want to test.

enter code here

And error message is shown as below:

java.lang.NullPointerException
at dao.DAOBase.getAll(DAOBase.java:37)
at dao.BlogCommentDAO.getAll(BlogCommentDAO.java:19)
at resource.BlogCommentResourceTest.setUp(BlogCommentResourceTest.java:29)
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.RunBefores.evaluate(RunBefores.java:24)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
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 io.dropwizard.testing.junit.ResourceTestRule$1.evaluate(ResourceTestRule.java:202)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:119)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42)
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)

Somebody know what happened? Why it is the DAOBase that throw a null pointer? My unit test for all of dao shows they works well.

SmartFingers
  • 105
  • 1
  • 8
  • I'd expect `POJOs.BlogCommentPOJO.toString()` is not being passed into `DAOBase`, otherwise your mock would be returning your list. – Chill Jun 03 '16 at 20:18
  • I think the issue is in the `setUp()` method. `at resource.BlogCommentResourceTest.setUp(BlogCommentResourceTest.java:29)` The only thing from a glance that I can see causing it is `POJOs.BlogCommentPOJO.toString()` returning `null`. Can you run the test, drop a breakpoint on that line and check? – Robert Bain Jun 03 '16 at 20:24
  • Thank you guys, I fix it. `BlogCommentDAO` is the object I mock, but actually I am trying to invoke method in BlogCommentDAO's superclass. I cancels their inheritance relationship, and copy the method to BlogCommentDAO, and it work. – SmartFingers Jun 03 '16 at 21:04

1 Answers1

1

The exception is thrown in dao.DAOBase.getAll(DAOBase.java:37) because the mock of dao returns null for dao.DAOBase. You seem to be mocking a class here, not an interface and are trying to access a field of this mocked class. This is not going to work, Mockito is designed to mock interface with class support being limited, and within that, to mock method behaviour, not field values.

To work around you the easiest is to turn your BlogCommentDAO into an interface or at least to have no public fields on it if it is a class, which then can be easily mocked like

DAOBase daoBaseMock = mock(DAOBase.class)
doReturn(allThings).when(daoBaseMock).getAll();
doReturn(daoBaseMock).when(dao).DAOBase();
Oleg Sklyar
  • 9,834
  • 6
  • 39
  • 62
  • DAOBase is BlogCommentDAO's father class, and the method I want to invoke is in DAOBase. Is this the thing? – SmartFingers Jun 03 '16 at 20:38
  • I do not understand that "father" class thing you mention. Can you post the definition of DAOBase within BlogCommentDAO? But yes, that is the thing-- DAOBase is null and you call a method on it – Oleg Sklyar Jun 03 '16 at 20:49
  • I mean superclass, sorry for that. I always call inheritance as child or father – SmartFingers Jun 03 '16 at 20:57
  • I thing the inheritance of dao is the thing, and I fix it. Many thanks. I shouldn't use inheritance, but instead, composition. – SmartFingers Jun 03 '16 at 21:03
  • I am sorry but I fail to see inheritance in this code of yours, thus cannot understand what you are describing. Either way, `dao.DAOBase` must be initialized or turned into a mocked method to get rid of the NPE – Oleg Sklyar Jun 03 '16 at 22:02