Мой девиз для 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 решения, которые, по вашему мнению, будут работать чище?