Generated test code for JVM Test Suite source set not marked as 'generated test sources root' in IntelliJ

41 Views Asked by At

I have a Gradle Java project using Google AutoValue to generate value classes. The project also applies Gradle's JVM Test Suite plugin and has a test suite for 'component tests'. This results in a new source set with directories src/componentTest/java and src/componentTest/resources.

AutoValue classes created in the src/main and src/test source sets work as expected. However, AutoValue classes in src/componentTest/java result in a compilation error in IntelliJ:

Compilation error in AutoValue class

This is because the generated class cannot resolve the source class (ComponentTestPojo):

Cannot resolve symbol error in generated class

I believe the problem is because IntelliJ is not marking the generated-test-sources-for-test-suite/app/build/generated/sources/annotationProcessor/java/componentTest folder as a 'generated test sources root'. The corresponding folder for unit tests are marked as such:

Folder structure

The .iml files for the unit and component test modules have a key difference that I believe explains this:

generated-test-sources-for-test-suite.app.test.iml:

<?xml version="1.0" encoding="UTF-8"?>
<module version="4">
  <component name="AdditionalModuleElements">
    <content url="file://$MODULE_DIR$/../../../app/build/generated/sources/annotationProcessor/java/test">
      <sourceFolder url="file://$MODULE_DIR$/../../../app/build/generated/sources/annotationProcessor/java/test" isTestSource="true" generated="true" />
    </content>
  </component>
</module>

generated-test-sources-for-test-suite.app.componentTest.iml:

<?xml version="1.0" encoding="UTF-8"?>
<module version="4">
  <component name="AdditionalModuleElements">
    <content url="file://$MODULE_DIR$/../../../app/build/generated/sources/annotationProcessor/java/componentTest">
      <sourceFolder url="file://$MODULE_DIR$/../../../app/build/generated/sources/annotationProcessor/java/componentTest" isTestSource="false" generated="true" />
    </content>
    <content url="file://$MODULE_DIR$/../../../app/src/componentTest" dumb="true">
      <sourceFolder url="file://$MODULE_DIR$/../../../app/src/componentTest/java" isTestSource="true" />
      <sourceFolder url="file://$MODULE_DIR$/../../../app/src/componentTest/resources" type="java-test-resource" />
    </content>
  </component>
</module>

Note that in the unit test file, the sourceFolder for the generated code path has isTestSource="true" whereas the component test file has isTestSource="false". If I manually change this to true, everything works as expected. However I cannot figure out how to rectify this in the build.gradle. Manual changes will be reverted when the project is reloaded.

It is worth noting that the project builds fine from the terminal when invoking ./gradlew clean build check so this is an IntelliJ-specific issue.

What configuration am I missing?

I have created a GitHub repository with a minimal reproducible example. I have also included the build.gradle file below:

/*
 * This file was generated by the Gradle 'init' task.
 *
 * This generated file contains a sample Java application project to get you started.
 * For more details on building Java & JVM projects, please refer to https://docs.gradle.org/8.5/userguide/building_java_projects.html in the Gradle documentation.
 */

plugins {
    // Apply the java-library plugin for API and implementation separation.
    id 'java-library'
    id 'jvm-test-suite'
}

repositories {
    // Use Maven Central for resolving dependencies.
    mavenCentral()
}

ext {
    autoValueVersion = "1.10.4"
}

dependencies {
    compileOnlyApi("com.google.auto.value:auto-value-annotations:${autoValueVersion}")

    annotationProcessor("com.google.auto.value:auto-value:${autoValueVersion}")
}

testing {
    suites {
        // Configure the built-in test suite
        test {
            // Use JUnit Jupiter test framework
            useJUnitJupiter('5.10.0')

            dependencies {
                compileOnly "com.google.auto.value:auto-value-annotations:${autoValueVersion}"

                annotationProcessor "com.google.auto.value:auto-value:${autoValueVersion}"
            }
        }

        componentTest(JvmTestSuite) {
            useJUnitJupiter('5.10.0')

            dependencies {
                compileOnly "com.google.auto.value:auto-value-annotations:${autoValueVersion}"

                annotationProcessor "com.google.auto.value:auto-value:${autoValueVersion}"
            }

            targets {
                all {
                    testTask.configure {
                        shouldRunAfter(test)
                    }
                }
            }
        }
    }
}

tasks.named('check') {
    dependsOn(testing.suites.componentTest)
}

// Apply a specific Java toolchain to ease working on different environments.
java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(21)
    }
}

My AutoValue class is as follows:

package com.example;

import com.google.auto.value.AutoValue;

@AutoValue
public abstract class ComponentTestPojo {

    public static Builder builder() {
        return new AutoValue_ComponentTestPojo.Builder();
    }

    public abstract String id();

    @AutoValue.Builder
    public static abstract class Builder {

        public abstract Builder id(final String id);

        public abstract ComponentTestPojo build();
    }
}
0

There are 0 best solutions below