Search code examples
javareflections

Configuration Reflections to scan test classes


Using Reflections library, I wrote a simple utility class that indexes all test methods together with their annotations. Reflections library helps me like that:

Reflections reflections = new Reflections(new ConfigurationBuilder()
  .setUrls(ClasspathHelper.forPackage(packageToIndex))
  .filterInputsBy(new FilterBuilder().includePackage(packageToIndex))
  .setScanners(
    new SubTypesScanner(false),
    new TypeAnnotationsScanner(),
    new MethodAnnotationsScanner()));

Set testMethods = reflections.getMethodsAnnotatedWith(Test.class);

If my utility class is located in sources root (src/main/java), it finds all test methods as expected.

However, if it is located in test root (src/test/java), then it finds no test methods.

How should I define ConfigurationBuilder for Reflections so that it works for the latter case?


Solution

  • I found a solution. When creating ConfigurationBuilder it is important to define:

    • register additional classloader that will be aware of test classes location
    • register test class location

    Here's an example implementation:

    URL testClassesURL = Paths.get("target/test-classes").toUri().toURL();
    
    URLClassLoader classLoader = URLClassLoader.newInstance(new URL[]{testClassesURL}, 
       ClasspathHelper.staticClassLoader());
    
    Reflections reflections = new Reflections(new ConfigurationBuilder()
            .addUrls(ClasspathHelper.forPackage(packageToIndex, classLoader))
            .addClassLoader(classLoader)
            .filterInputsBy(new FilterBuilder().includePackage(packageToIndex))
            .setScanners(
                    new SubTypesScanner(false),
                    new TypeAnnotationsScanner(),
                    new MethodAnnotationsScanner()));