13

I am trying to mock a static method with parameters like this :

Mockito.when(StaticClass.staticMethod(Mockito.any(A.class), 
                                      Mockito.any(B.class), SomeEnum.FOO))
       .thenReturn(true);

I have added the following annotations :

@RunWith(PowerMockRunner.class)
@PowerMockRunnerDelegate(Parameterized.class)
@PrepareForTest({StaticClass.class, A.class, B.class})

But Mockito.any always returns null. Why ?

Turing85
  • 18,217
  • 7
  • 33
  • 58
Eko
  • 1,487
  • 1
  • 18
  • 36
  • As written in my answer - you should step back and read [mcve] and enhance your question accordingly. – GhostCat Nov 06 '17 at 15:28

4 Answers4

14

Short answer: Use doReturn().when() instead of when().then()

Long answer can be found over here: How do Mockito matchers work?

Matchers return dummy values such as zero, empty collections, or null. Mockito tries to return a safe, appropriate dummy value, like 0 for anyInt() or any(Integer.class) or an empty List for anyListOf(String.class). Because of type erasure, though, Mockito lacks type information to return any value but null for any()

NullPointerException or other exceptions: Calls to when(foo.bar(any())).thenReturn(baz) will actually call foo.bar(null), which you might have stubbed to throw an exception when receiving a null argument. Switching to doReturn(baz).when(foo).bar(any()) skips the stubbed behavior.

Side Note: This issue could also be described something like, How to use Mockito matchers on methods that have precondition checks for null parameters?

Community
  • 1
  • 1
Aaron Gehri
  • 148
  • 1
  • 7
5

Firstly, you can't mix matchers with actual arguments. You should use a matcher for the SomeEnum argument too:

Mockito.when(StaticClass.staticMethod(Mockito.any(A.class), 
                                      Mockito.any(B.class), Mockito.eq(SomeEnum.FOO))
       .thenReturn(true);

Secondly, the any() methods should return null. That is exactly what they do. If you look at the code for these methods they return the default value for the class type if it is primitive wrapper object (like Integer, Boolean etc.) otherwise it returns null:

public <T> T returnFor(Class<T> clazz) {
    return Primitives.isPrimitiveOrWrapper(clazz) ? Primitives.defaultValueForPrimitiveOrWrapper(clazz) : null;
}
Plog
  • 9,164
  • 5
  • 41
  • 66
  • Still returns null :( even the Mockito.eq returns null I have added `PowerMockito.spy(StaticClass.class);` in the @Before method – Eko Nov 06 '17 at 15:06
  • I've just realised the any() method does return null for these cases. It returns the default value for the class so null for all objects and the default primitive value for primitive wrapper classes like Integer. So it isn't wrong that these methods return null. What is actually going wrong in your test? – Plog Nov 06 '17 at 15:16
  • My staticMethod checks if the parameters are null – Eko Nov 06 '17 at 15:29
1

You are getting things wrong. The one and only purpose of matcher methods such as any() is to match the arguments that come in at execution time.

You use these methods to instruct the mocking framework what calls you expect to happen. Or the other way round you use them to say: if this or that is coming in as argument then do this or that.

Therefore you absolutely do not care about the results of matcher invocations.

In that sense your question is indicating that your usage of the mocking framework is going the wrong way. Thus the only answer we can give regarding your current input: A) do some more research how to use mocking and B) then rework your question to be clear about your problem.

GhostCat
  • 137,827
  • 25
  • 176
  • 248
  • If you are using Mockito to wrap an existing object, calling `when(real.method(any(klass)))` eventually calls the real method with a `null`, throwing a NPE during test setup. Assuming changing the object `real` is beyond my scope, what else can be done? – Stewart Jan 22 '18 at 15:48
1

It was because it was a Parameterized test, and I did the mockStatic in the @Before method. When I do the mockStatic in the same method, it works.

Eko
  • 1,487
  • 1
  • 18
  • 36