I have a static methods class, Utils, that is basically for utility methods, its used by almost every class. It does things like get files and other basic stuff. My tester went and changed this class to a singleton so that every class using Utils now has to call getInstance(). The reason was that he couldn’t test certain things unless this was the case. It seems to me that this is wrong in some ways and that this could lead to issues.
public class Utils {
/**
* Singleton method to allow for easier testing.
* @return an instance of
*/
public synchronized static Utils getInstance() {
if (instance == null) {
instance = new Utils();
}
return instance;
}
public synchronized static void setInstance(Utils instance) {
Utils.instance = instance;
}
/** Singleton to make testing easier **/
private static Utils instance = null;
public static boolean checkOSTen() {
return getInstance()._checkOSTen();
}
private boolean _checkOSTen() {
boolean autoPair = false;
if (android.os.Build.VERSION.SDK_INT >= 10){
autoPair = true;
}
return autoPair;
}
}
By the way I have a very complex system of internal messaging that uses at least 7 threads to send messages and wanted to see if there is an impact of static method calls vs Singleton static method calls.
Is there another way to do testing other than this? Seems some Java reflection would get what you need.
Your tester probably finds this code difficult to test as they can’t easily change the return value of
android.os.Build.VERSION.SDK_INT, and therefore they can’t easily test the different code paths that are used depending on this return value. By using an instance method they can use a mocking framework to fake the_checkOSTenmethod to return eithertrueorfalse, depending on what they are trying to test.Another way to do testing is to not use static methods such as these at all, and instead use class (perhaps called
DeviceCapabilities) which will be injected via a setter or a constructor into every other class that requires knowledge of the version of the OS.Then, your tester could easily pass instances of
DeviceCapabilitiesto whichever class needed access to this information.That said, at this stage in your build it may be too late to make a change like this so the change your tester has made is a reasonable compromise.