6

I'm converting some tests from Mockito 1.x to 2.15.0.

Dealing with the new treatment of "null" values was relatively straightforward for String parameters. It appears to be a little more difficult for Map parameters, but I think I'd have the same problem with any type using type parameters.

I've tried the following alternatives:

  1. anyMap()
  2. isNull()
  3. nullable(Map.class)
  4. (Map<KeyType,ValueType>) nullable(Map.class)

The first was the original before the 2.x conversion. It doesn't match if the value is null. The second works if the value is always null, but I don't like it, as it drops type information in the test. The third seems like it would be correct, but it doesn't compile, as the formal parameter type uses generics. The fourth works, but I don't like the cast being there.

Is there a cleaner solution for this?

Jeff Bowman
  • 90,959
  • 16
  • 217
  • 251
David M. Karr
  • 14,317
  • 20
  • 94
  • 199
  • 1
    Beyond the helpful answer: it might be helpful to have explicit testcases. You should *know* wether your testcase will be using null or non-null. – GhostCat Oct 26 '18 at 10:55

1 Answers1

3

Use any() for this. Unlike any(Class<T> clazz) or anyMap(), Mockito allows any to match null as a value.

For the historically-curious: Brice explains the etymology here. any(T.class) looks like "any T", for which null makes less sense and any(T.class) takes the same instanceof-like semantics as isA(T.class). any() still properly stands for "any value" including null.

There are other solutions, such as or(isNull(), anyMap()), but they're redundant: Java will ensure that the only passable values are null or the properly-generic Map, and in Java 8 and beyond inference has improved to the point that Java will correctly infer your Map including the generics.

See also: What's the difference between Mockito Matchers isA, any, eq, and same?

Jeff Bowman
  • 90,959
  • 16
  • 217
  • 251