Этот вопрос может быть старым, но так как это был ближайший ответ, который я нашел, когда у меня возникла эта проблема, я решил описать свое решение.
Использование JUnit 4
Разделите ваши тесты так, чтобы в каждом классе был один метод тестирования (это решение изменяет загрузчики классов только между классами, а не между методами, поскольку родительский исполнитель собирает все методы один раз для каждого класса)
Добавьте аннотацию @RunWith(SeparateClassloaderTestRunner.class)
к вашим тестовым классам.
Создайте SeparateClassloaderTestRunner
, чтобы он выглядел так:
public class SeparateClassloaderTestRunner extends BlockJUnit4ClassRunner {
public SeparateClassloaderTestRunner(Class<?> clazz) throws InitializationError {
super(getFromTestClassloader(clazz));
}
private static Class<?> getFromTestClassloader(Class<?> clazz) throws InitializationError {
try {
ClassLoader testClassLoader = new TestClassLoader();
return Class.forName(clazz.getName(), true, testClassLoader);
} catch (ClassNotFoundException e) {
throw new InitializationError(e);
}
}
public static class TestClassLoader extends URLClassLoader {
public TestClassLoader() {
super(((URLClassLoader)getSystemClassLoader()).getURLs());
}
@Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
if (name.startsWith("org.mypackages.")) {
return super.findClass(name);
}
return super.loadClass(name);
}
}
}
Примечание. Я должен был сделать это, чтобы протестировать код, работающий в устаревшей среде, которую я не мог изменить. Если бы у меня был выбор, я бы сократил использование статики и / или установил тестовые зацепки, чтобы система могла быть перезагружена. Это может быть не красиво, но позволяет мне тестировать очень много кода, который в противном случае был бы сложным.
Также это решение ломает все остальное, что основано на хитростях загрузки классов, таких как Mockito.