Мой девиз для Java: «То, что в Java есть статические блоки, не означает, что вы должны их использовать». Помимо шуток, в Java есть множество уловок, которые превращают тестирование в кошмар. Два из них, которые я больше всего ненавижу, - это анонимные классы и статические блоки. У нас есть много унаследованного кода, в котором используются статические блоки, и это один из раздражающих моментов при написании модульных тестов. Наша цель - иметь возможность писать модульные тесты для классов, которые зависят от этой статической инициализации, с минимальными изменениями кода.
Пока что я предлагаю моим коллегам переместить тело статического блока в частный статический метод и назвать его staticInit
. Затем этот метод можно вызвать из статического блока. Для модульного тестирования другой класс, зависящий от этого класса, может легко имитировать staticInit
с помощью JMockit, чтобы ничего не делать. Посмотрим на это на примере.
public class ClassWithStaticInit {
static {
System.out.println("static initializer.");
}
}
Будет изменен на
public class ClassWithStaticInit {
static {
staticInit();
}
private static void staticInit() {
System.out.println("static initialized.");
}
}
Чтобы мы могли делать следующее в JUnit.
public class DependentClassTest {
public static class MockClassWithStaticInit {
public static void staticInit() {
}
}
@BeforeClass
public static void setUpBeforeClass() {
Mockit.redefineMethods(ClassWithStaticInit.class, MockClassWithStaticInit.class);
}
}
Однако это решение также связано со своими проблемами. Вы не можете запускать DependentClassTest
и ClassWithStaticInitTest
на одной JVM, поскольку вы действительно хотите, чтобы статический блок работал для ClassWithStaticInitTest
.
Как бы вы справились с этой задачей? Или какие-либо лучшие решения, не основанные на JMockit, которые, по вашему мнению, будут работать чище?