public class AnnotationProcessorTestRunner
extends org.junit.runners.BlockJUnit4ClassRunner
The environment of the test is setup using annotations, either on the class or on the test method.
On the test class:
@ProcessorUnderTest: Indicates the class of the processor under
test.@InitializeProcessorField: Indicates the name of a field on
the test class that has the processor under test. The processor must be instantiated and the
field set in a set-up step (i.e. @Before method). If neither this annotation nor
ProcessorUnderTest is present, no processor is setup. If a test methods needs to invoke
methods on an instance of a processor, it will have to instantiate the processor itself.@OptionsForProcessing: Indicates the sequence of options (like
command-line options) that are provided to the Java compiler. These can include options
interpreted by the processor under test.@FilesToProcess: Indicates the set of input files (like source and
resource files) for the Java compiler and the annotaiton processor.@ClassesToProcess: Indicates the set of classes to process. These
classes will be included in the root elements on each round of processing, even if there are no
input files to process.@ValidateGeneratedFiles: Indicates a set of "golden" output
files. When the processor completes, the test runner will verify that the processor produced the
correct output by comparing it to these files.@SupportedSourceVersion: Usually the supported source version
comes from the processor under test. But if neither ProcessorUnderTest nor
InitializeProcessorField is used, then you can use this annotation on the test class to
provide this information.@SupportedAnnotationTypes: Same remarks as for
SupportedSourceVersion. If a test does not otherwise define a processor for testing, this
annotation can be used to provide this information to the environment. Also same notes about
inheritance of this annotation.@SupportedOptions: Same remarks again as for
SupportedSourceVersion and SupportedAnnotationTypes.On the test method:
@NoProcess: Indicates that a given method is a normal test method. The
processing environment will not be setup for this method.@Reentrant: Indicates that a given method can be called more than once if
the processing phase results in multiple rounds. So the method may be called more than once
during the course of a single test case, once for each round.@ProcessorUnderTest: This is the same as used on the class, except
that it overrides the processor to test for a single method.@OptionsForProcessing: This is the same as used on the class,
except that it overrides the options for a single method. It can also be used to add to
the options that are defined on the class.@FilesToProcess: This is the same as used on the class, except that it
overrides the files used for a single method. It can also be used to add to the set of
files that are defined on the class.@ClassesToProcess: This is the same as used on the class, except
that it overrides the classes processed for a single method. It can also be used to
add to the set of classes that are defined on the test class.@ValidateGeneratedFiles: This is the same as used on the
class, except that it overrides the output files to validate for a single method. It can also be
used to add to the set of validated output files that are defined on the class.Unlike normal test methods, tests run by AnnotationProcessorTestRunner can accept
arguments. That is how the test method gets access to the processing environment. Test methods'
can have arguments of the following types:
TestEnvironment: a reference to the test environment, including accessor methods for
everything else and a few extra utility methods, too. This is really the only thing any test
method needs, but the other types are supported for convenience.TestJavaFileManager or JavaFileManager: a reference to the Java compiler's
file manager.CategorizingDiagnosticCollector: a reference to the collector of diagnostics emitted
by the Java compiler. (See DiagnosticListener.)ProcessingEnvironment: a reference to the processing environment.Elements: a reference to the utility class for working with elements. (See
ProcessingEnvironment.getElementUtils()).Types: a reference to the utility class for working with type mirrors. (See
ProcessingEnvironment.getTypeUtils()).Filer: a reference to the interface used by an annotation processor to read and write
files. (See ProcessingEnvironment.getFiler()).Messager: a reference to the interfaced used by an annotation processor to emit
messages and/or diagnostics. (See ProcessingEnvironment.getMessager()).SourceVersion: a reference to the current version of the source code being processed.
See ProcessingEnvironment.getSourceVersion()).Map<String, String>: a reference to the current options. See
ProcessingEnvironment.getOptions()).RoundEnvironment: a reference to the current round environment.Set<TypeElement>: a reference to the set of annotation types for
the current round of processing.? extends Processor: a reference to the processor under test. If the method
accepts a sub-class or sub-interface of Processor that is not compatible with the actual
processor instance under test, the test method will fail with a ClassCastException.boolean, which represents the return value of
executing Processor.process(Set, RoundEnvironment) and indicates whether the annotations
for that round were consumed by the processor.
Note that a method annotated with @NoProcess must accept no arguments and
return void since it is run as a normal test method.
Here is a short example of a test.
@RunWith(AnnotationProcessorTestRunner.class)
@FilesToProcess( @InputFiles({"test/my/package/MyClass1.java", "test/my/package/MyClass2.java"}))
@ClassesToProcess({SomeClassWithAnnotations.class, AnotherClassWithAnnotations.class})
@SupportedSourceVersion(SourceVersion.RELEASE_6)
public class MyAnnotationProcessorTest {
// You can specify @FilesToProcess and/or @ClassesToProcess for a given method, and it
// will override the values specified at the class level.
@Test public void someTest(TestEnvironment testEnv) {
// Do something in the environment -- like unit tests on processor methods that require tool context.
// If we had defined a processor using @ProcessorUnderTest or
// @InitializeProcessorField annotations, we could simply do this:
// testEnv.invokeProcessor();
// To construct and run a processor (like to run a processor that hasn't been setup using
// @ProcessorUnderTest or @InitializeProcessorField):
SomeOtherProcessor processor = new SomeOtherProcessor();
processor.init(testEnv.processingEnvironment());
processor.process(testEnv.filterAnnotationsFor(processor), testEnv.roundEnvironment());
// TestEnvironment provides other methods for doing verification/assertions on processor
// output.
FileObject generatedFile = testEnv.fileManager().getFileForInput(
StandardLocation.CLASS_OUTPUT, "", "path/to/generated/file");
testEnv.validateGeneratedFile(generatedFile, "path/to/resource/against/which/to/compare");
// Test method can return boolean to indicate whether annotations are "claimed". If test method
// returns void, assume annotations claimed. Note: if the test method is marked as @Reentrant
// and the compiler performs another round of processing, the test method will be called again
// during the same javac invocation, once for each subsequent round.
}
}
| Constructor and Description |
|---|
AnnotationProcessorTestRunner(Class<?> klass) |
| Modifier and Type | Method and Description |
|---|---|
protected org.junit.runners.model.Statement |
methodInvoker(org.junit.runners.model.FrameworkMethod method,
Object test) |
protected void |
validateInstanceMethods(List<Throwable> errors) |
protected org.junit.runners.model.Statement |
withBefores(org.junit.runners.model.FrameworkMethod method,
Object target,
org.junit.runners.model.Statement statement) |
collectInitializationErrors, computeTestMethods, createTest, describeChild, getChildren, getTestRules, methodBlock, possiblyExpectingExceptions, rules, runChild, testName, validateConstructor, validateNoNonStaticInnerClass, validateOnlyOneConstructor, validateTestMethods, validateZeroArgConstructor, withAfters, withPotentialTimeoutpublic AnnotationProcessorTestRunner(Class<?> klass) throws org.junit.runners.model.InitializationError
org.junit.runners.model.InitializationErrorprotected org.junit.runners.model.Statement withBefores(org.junit.runners.model.FrameworkMethod method,
Object target,
org.junit.runners.model.Statement statement)
withBefores in class org.junit.runners.BlockJUnit4ClassRunnerprotected org.junit.runners.model.Statement methodInvoker(org.junit.runners.model.FrameworkMethod method,
Object test)
methodInvoker in class org.junit.runners.BlockJUnit4ClassRunner