Проблема со статическими методами и классами заключается в том, что вы не можете переопределить их для двойников теста. Это делает модульное тестирование намного сложнее. У меня все переменные объявлены как финальные и инициализированы в конструкторе. Все, что необходимо, передается в качестве параметров конструктору (внедрение зависимости). Таким образом, вы можете заменить удвоенные значения тестов для некоторых параметров во время модульных тестов.
Например:
public class MyAppProps {
protected static final String PROP_FILENAME = "myapp.properties";
protected Properties props = null;
public String DATABASE_NAME = "database_name";
public String DATABASE_USER = "database_user";
// etc...
public MyAppProps(InputStream is) throws MyAppException {
try {
props = new Properties();
props.load(is);
} catch (Exception e) {
threw new MyAppException(e.getMessage());
}
}
public String getProperty(String name) {
return props.getProperty(name);
}
// Need this function static so
// client objects can load the
// file before an instance of this class is created.
public static String getFileName() {
return PROP_FILENAME;
}
}
Теперь вызовите его из производственного кода следующим образом:
String fileName = MyAppProps.getFileName();
Classloader loader = MyAppException.class.getClassLoader();
InputStream is = loader.getResourceAsStream(fileName);
MyAppProps p = new MyAppProps(is);
Внедрение зависимостей происходит, когда вы включаете входной поток в параметры конструктора. Хотя это немного сложнее, чем использование статического класса / Singleton, при выполнении модульных тестов все становится просто невозможным.
Для модульного тестирования это может выглядеть примерно так:
@Test
public void testStuff() {
// Setup
InputStringTestDouble isTD = new InputStreamTestDouble();
MyAppProps instance = new MyAppProps(isTD);
// Exercise
int actualNum = instance.getProperty("foo");
// Verify
int expectedNum = 42;
assertEquals("MyAppProps didn't get the right number!", expectedNum, actualNum);
}
Внедрение зависимостей позволило очень просто заменить тестовый двойник для входного потока. Теперь просто загрузите все, что вы хотите, в тестовый двойник, прежде чем передавать его конструктору MyAppProps. Таким образом, вы можете проверить, как свойства загружаются очень легко.