1 package top.infra.test.classloader.exclude;
2
3 import lombok.SneakyThrows;
4
5 import org.junit.runner.Runner;
6 import org.junit.runners.BlockJUnit4ClassRunner;
7 import org.junit.runners.Suite;
8 import org.junit.runners.model.InitializationError;
9
10 import java.net.URLClassLoader;
11 import java.util.ArrayList;
12 import java.util.Arrays;
13 import java.util.List;
14
15 import top.infra.test.classloader.ClassLoaderChangerRunner;
16 import top.infra.test.classloader.ClassUtils;
17
18 public class ExcludeClassJunitRunner extends Suite {
19
20 private static URLClassLoader currentClassLoader;
21 private static ExcludeClassesClassLoader customClassLoader;
22
23 static {
24 currentClassLoader = (URLClassLoader) Thread.currentThread().getContextClassLoader();
25 customClassLoader = new ExcludeClassesClassLoader(
26 currentClassLoader,
27 currentClassLoader.getURLs(),
28 null
29 );
30 }
31
32 public ExcludeClassJunitRunner(final Class<?> klass) throws InitializationError {
33 super(
34 ClassUtils.loadFromCustomClassloader(customClassLoader, klass),
35 buildRunners(ClassUtils.loadFromCustomClassloader(customClassLoader, klass)));
36 }
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54 @SneakyThrows
55 private static List<Runner> buildRunners(final Class<?> klass) {
56 final ExcludeClasses excludeClasses = klass.getAnnotation(ExcludeClasses.class);
57 if (excludeClasses == null) throw new IllegalArgumentException("Class " + klass + " is missing ExcludeClasses annotation");
58
59 customClassLoader.setExcludes(Arrays.asList(excludeClasses.excludesClasses()));
60
61 final Class<?> testClass = customClassLoader.loadClass(klass.getName());
62
63 final Class<?> runnerClass = excludeClasses.runner();
64 final BlockJUnit4ClassRunner junit4Runner =
65 (BlockJUnit4ClassRunner) runnerClass.getConstructor(Class.class).newInstance(testClass);
66
67 final List<Runner> runners = new ArrayList<>();
68 runners.add(new ClassLoaderChangerRunner(currentClassLoader, customClassLoader, junit4Runner));
69 return runners;
70 }
71 }