16

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.

5
  • add stacktrace of your NPE Commented Mar 28, 2016 at 23:15
  • 2
    You have to stub on a specific mock object - I don't believe you can do when(any(T.class)....). Commented Mar 28, 2016 at 23:16
  • That's my guess as well. But compiler is not complaining, hence I thought let me ask. Commented Mar 28, 2016 at 23:20
  • "Compiler doesn't complain" != "my code is fine" ;). Also, your stacktrace doesn't involve Mockito at all... Commented Mar 28, 2016 at 23:22
  • Thanks @OliverCharlesworth . Yeah I am not sure why there is no mockito, but it does fail over there. At least according to intellij(ShellTest.java:139 is that line). But anyway if this is not the way to go. I'll find some other way. Commented Mar 28, 2016 at 23:27

3 Answers 3

14

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?".

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks Jeff. That helped. I'll save that other Q.
2

To extend on what @jeff-bowman said in his answer, any() returns null, so if you need something that doesn't return null, you can try this:

/** * never returns null */ private inline fun <reified T> any(type: Class<T>): T = Mockito.any(type) /** * returns null */ private inline fun <reified T> any(): T = Mockito.any<T>() 

1 Comment

This is an excellent solution, worked as intended.
2

For me the actual problem was that I was trying to mock a spy. When mocking a spy you have to use the doReturn or doAnswer methods. Otherwise the method of the spy will be actually called while trying to mock it and unexpected behavior can happen. E.g. when calling when with any(), any() will just return null. So it is likely that you will get an NullPointerException.

Here is a full example that demonstrates the bahavior:

package com.company; import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.*; public class SpyTest { public class Controller { public String method(String arg) { return arg.substring(0, 1); } } @Test public void withMockTest() { Controller controllerMocked = mock(Controller.class); when(controllerMocked.method(anyString())).thenReturn("42"); assertEquals("42", controllerMocked.method("FOO")); } @Test(expected = NullPointerException.class) public void withSpyWhenThenReturnBreakingBecauseMethodToBeMockedIsActuallyBeingCalled() { Controller controllerSpied = spy(new Controller()); when(controllerSpied.method(any())).thenReturn("42"); } @Test public void withSpyDoReturnWhen() { Controller controllerSpied = spy(new Controller()); doReturn("42").when(controllerSpied).method(any()); assertEquals("42", controllerSpied.method("FOO")); } } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.