Passing null to overloaded methods

Assume we have an overloaded method that looks like this:

public String retrieveValue(String text) {
    return text;
}

public int retrieveValue(int number) {
    return number;
}

Pretty nice overloading, eh?! What could go wrong, for retrieveValue(null) method? In the above code, nothing, because the method with the String signature will be invoked, as the one with the int signature is just of type primitive, so, it’s almost obvious for the compiler.

However, can you imagine what would happen, if the second method accepted an argument of Integer?

public String retrieveValue(String text) {
    return text;
}

public int retrieveValue(Integer number) {
    return number;
}

Integer is the wrapper class of int and what generally stands for the wrapper classes of primitives is that they can also accept null values. So, calling retrieveValue(null) in this case will just confuse the compiler, ‘cuz it’s just ambiguous for him which method to pick up, since both of them can accept a null value argument.

Therefore, there will be a compilation error of:

Ambiguous method call. Both 
retrieveValue (String) in TestClass and
retrieveValue (Integer) in TestClass match

Cheers!

NullPointerException in Mockito

Of course this was identified in the testing phase.

So, in my unit test, I was mocking the interface  and then calling the corresponding service to perform a unit test.

However, while debugging the failed test, it threw a NullPointerException at the point where the unit made the actual call to the service through the interface.

My interface was @Autowired. What could go wrong? Why couldn’t the instantiate the @Autowired interface? I have properly injected it to the test, too.

Ok, let’s start reading both the test and the unit from the beginning: in the test part, everything seemed to be fine; mocking the offending interface, providing the preconditions and calling the offending service properly.

Started reading the service of the unit itself guided me to the error. I never autowired any interface. The only thing I injected and autowired was the service itself. Of course, this thing worked pretty well on the user’s side, because no matter of what you define as your caller (interface or service), the method that has to be called will be called in the end, because both of them can call it (the only difference is that the call through interface is “implicit” and the other “explicit”),  but by the time I mocked the interface in the test and setup any preconditions to be dependant on the interface, it would onbivously throw a NPE, because I hadn’t specified anything for the implementation, in the unit test.

Changing the implementation to inject the offending interface instead of the implementation of it, resolved the problem, because then, Mockito could identify the interface, because I had already set it properly up in the test, whereas previously it threw NPE, because I was just trying to setup a precondition for something (interface) that wasn’t actually used in the unit class itself (implementation was injected  instead).

Conclusion

Both interfaces and implementations can be marked as @Autowired, but be careful when unit testing. For example, in my case, with Mockito, I setup my test around the interface, whereas the offending unit had the implementation injected, instead.

Cheers