Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mockito NullPointerException while using any

Tags:

junit4

mockito

I am trying to use Mockito like this :

    Mockito.when(Mockito.any(ObjectMapper.class).readValue(Mockito.any(BufferedReader.class),Mockito.any(Class.class))).thenReturn(new Person("1","abc"));

This is from Jackson library .

public <T> T readValue(Reader src, Class<T> valueType)

The reason I am doing it is because the time I reach this point of the code there are a ton of objects which were created. Mocking on every step would take time.

Any reason why I am getting NPE when code reaches this mockito statement?

Stack Trace :

java.lang.NullPointerException
    at com.prashant.flax.ShellTest.givenDirectoryHasFiles(ShellTest.java:139)
    at com.prashant.flax.ShellTest.testExecute(ShellTest.java:61)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:48)
    at org.junit.rules.RunRules.evaluate(RunRules.java:20)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:78)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)

As you can see it is in a given method(this method only has this piece of code) , so I can see while debugging, it reaches over there and crashes.

like image 383
Prashant Avatar asked Mar 28 '16 23:03

Prashant


1 Answers

As Oliver mentioned in the comments, you can't apply when to happen to all objects. Mockito works via subclassing, so you have to create a mock instance using mock, spy, or a @Mock or @Spy annotation; customize the behavior; and then install the mock using dependency injection or other similar tricks.


As to why this happens, the return value for any() actually is null; matchers like any are only supposed to be used as arguments to when and verify, and Mockito can't produce a specialized instance of Class that represents "any Class", so Mockito returns a dummy value (null) and stores data on a specialized stack of argument matchers. Though Mockito has better error messages to alert you to this situation, your code NPEs before Mockito can give you a proper exception with usage examples.

For more about matcher return values and the stack, see my other SO answer on "How do Mockito matchers work?".

like image 68
Jeff Bowman Avatar answered Sep 23 '22 06:09

Jeff Bowman