Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

call static method on parameter without instantiating class in argument

Tags:

java

I've really been getting into TDD and I've started using mockito in jUnit to improve my ability to test code. I'm really loving mockito!

I've noticed that I have to change the way I think about coding, like passing collaborators as much as possible into methods and limiting work done in constructors wherever possible.

The following scenario warranted some advice from the experts here on SO.

Say I have a method, that's going to call some static methods on a certain class. E.G.

public void method(){
    OtherClass.staticMethod();
}

This is generally bad, but it's needed in my scenario. To make the code more testable in my unit tests I'd like to avoid the dependency on OtherClass and pass it as an argument.

This doesn't work as it yields a compile time error.

public void method(Class<? extends OtherClass> util){
    util.staticMethod();
}
...
method(OtherClass.class);

This would work, but I don't like the instantiating OtherClass if I don't have to, as it's solely a class of static utility like methods:

public void method(OtherClass util){
     util.staticMethod();
}
...
method(new OtherClass());

My question to you: Is there a better more preferable way to accomplish this without using the new keyword?

like image 988
jsdevel Avatar asked May 06 '13 06:05

jsdevel


1 Answers

This would work, but I don't like the instantiating OtherClass if I don't have to, as it's solely a class of static utility like methods:

public void method(OtherClass util){
     util.staticMethod();
}
...
method(new OtherClass());

Actually, this doesn't work, as it will always invoke the method implementation from OtherClass, irrespective of the object you pass (even if you pass null).

I strongly recommend not to use reflection just to simplify testing, as this bypasses compile time checking (a wrongly spelled method name will not be detected by the compiler), and prevents the use of many features of your IDE (code completion, javadoc hovers, refactoring support, call hierarchy display, jump to definition, ...)

The common approach is to use polymorphic dispatch. In Java, this requires the method to be not static and not private. The rule of thumb therefore is: If it needs mocking, it shouldn't be static.

How to best obtain the object instance depends on your circumstances; dependency injection (your approach), the resource locator pattern, and the singleton pattern each have their own advantages and disadvantages.

like image 191
meriton Avatar answered Oct 20 '22 19:10

meriton