Прежде всего, вот отличная статья с советами по модульному тестированию . Во-вторых, я нашел отличный способ избежать внесения множества изменений в старый код - просто немного реорганизовать его, пока вы не сможете его протестировать. Один из простых способов сделать это - защитить закрытых участников, а затем переопределить защищенное поле.
Например, допустим, у вас есть класс, который загружает некоторые вещи из базы данных во время конструктора. В этом случае вы не можете просто переопределить защищенный метод, но вы можете извлечь логику БД в защищенное поле и затем переопределить ее в тесте.
public class MyClass {
public MyClass() {
// undesirable DB logic
}
}
становится
public class MyClass {
public MyClass() {
loadFromDB();
}
protected void loadFromDB() {
// undesirable DB logic
}
}
и тогда ваш тест выглядит примерно так:
public class MyClassTest {
public void testSomething() {
MyClass myClass = new MyClassWrapper();
// test it
}
private static class MyClassWrapper extends MyClass {
@Override
protected void loadFromDB() {
// some mock logic
}
}
}
Это несколько плохой пример, потому что вы можете использовать DBUnit в этом случае, но я недавно сделал это в аналогичном случае, потому что я хотел протестировать некоторые функции, совершенно не связанные с загружаемыми данными, поэтому это было очень эффективно , Я также обнаружил, что такое разоблачение членов было полезно в других подобных случаях, когда мне нужно избавиться от некоторой зависимости, которая была в классе в течение длительного времени.
Я бы порекомендовал против этого решения, если вы пишете фреймворк, если только вы действительно не против выставить участников пользователям вашей фреймворк.
Это что-то вроде хака, но я нашел это весьма полезным.