|
| 1 | +--- |
| 2 | +layout: default |
| 3 | +used_in_navigation: true |
| 4 | +menu_name: Testing Annotation Processors |
| 5 | +order: 3 |
| 6 | +--- |
| 7 | + |
| 8 | +# Testing Annotation Processors |
| 9 | + |
| 10 | +Testing of annotation processors is very tricky. Your annotation processors heavily rely on the _ProcessingEnvironment_ tools. |
| 11 | +Those tools offer you access to the java compile time model and cannot be mocked or simulated very easily in unit tests. |
| 12 | + |
| 13 | +So best way to test your annotation processors is to actually do a compile time test. Doing this all tools offered by the _ProcessingEnvironment_ are provided by the compiler. |
| 14 | +This can be done by using the com.google.testing.compile compile-testing framework which allows to do compilations of some test source code during your tests and to check the outcomes. |
| 15 | +One thing to mention is that JDK >=6 is supported up to version 0.9 - all following versions are base on JDK >=8. |
| 16 | + |
| 17 | +This project simplifies testing even more by hiding the complexity of using the compile-testing framework. |
| 18 | + |
| 19 | +We will show you what needs to be done in the following... |
| 20 | + |
| 21 | +## Setting up a test |
| 22 | + |
| 23 | +Setting up a junit test is quite easy. This framework is using parameterized unit tests to do some testing. |
| 24 | + |
| 25 | +Here's a small example for a testcase that validates the compile outcome. This is quite useful for annotation processors that are doing validations about the usage of annotations: |
| 26 | + |
| 27 | + package de.holisticon.example.annotationprocessortoolkit.annotationprocessor; |
| 28 | + |
| 29 | + import de.holisticon.annotationprocessortoolkit.testhelper.AbstractAnnotationProcessorTest; |
| 30 | + import org.junit.Test; |
| 31 | + import org.junit.runner.RunWith; |
| 32 | + import org.junit.runners.Parameterized; |
| 33 | + |
| 34 | + import java.util.Arrays; |
| 35 | + import java.util.List; |
| 36 | + |
| 37 | + |
| 38 | + @RunWith(Parameterized.class) |
| 39 | + public class MethodWithOneStringParameterAndVoidReturnTypeProcessorTest extends AbstractAnnotationProcessorTest<MethodWithOneStringParameterAndVoidReturnTypeAnnotationProcessor> { |
| 40 | + |
| 41 | + |
| 42 | + public MethodWithOneStringParameterAndVoidReturnTypeProcessorTest(String description, String resource, String[] errors, String[] warnings) { |
| 43 | + super(description, resource, errors, warnings); |
| 44 | + } |
| 45 | + |
| 46 | + @Override |
| 47 | + protected MethodWithOneStringParameterAndVoidReturnTypeAnnotationProcessor getAnnotationProcessor() { |
| 48 | + return new MethodWithOneStringParameterAndVoidReturnTypeAnnotationProcessor(); |
| 49 | + } |
| 50 | + |
| 51 | + @Parameterized.Parameters(name = "{index}: \"{0}\"") |
| 52 | + public static List<Object[]> data() { |
| 53 | + |
| 54 | + return Arrays.asList(new Object[][]{ |
| 55 | + {"Test valid usage", "testcases/methodWithOneStringParameterAndVoidReturn/ValidUsageTest.java", new String[]{}, new String[]{}}, |
| 56 | + {"Test invalid usage : non void return type", "testcases/methodWithOneStringParameterAndVoidReturn/InvalidUsageNonVoidReturnType.java", new String[]{"Method must have void return type"}, new String[]{}}, |
| 57 | + {"Test invalid usage : non String parameter", "testcases/methodWithOneStringParameterAndVoidReturn/InvalidUsageNonStringParameter.java", new String[]{"Method must have parameters of types [java.lang.String], but has parameters of types [java.lang.Object]"}, new String[]{}}, |
| 58 | + |
| 59 | + }); |
| 60 | + |
| 61 | + } |
| 62 | + |
| 63 | + |
| 64 | + @Test |
| 65 | + public void testCorrectnessOfAdviceArgumentAnnotation() { |
| 66 | + super.test(); |
| 67 | + } |
| 68 | + |
| 69 | +So basically you need to do the following things: |
| 70 | + |
| 71 | +1. Create a test class which should extend the abstract _AbstractAnnotationProcessorTest<YourAnnotationPracessor>_ class |
| 72 | +2. Implement the abstract method _getAnnotationProcessor_ declared by the _AbstractAnnotationProcessorTest<YourAnnotationPracessor>_ class. It should return an instance of the annotation processor to use. |
| 73 | +3. Add the annotation _@Parameterized_ to the class |
| 74 | +4. Create a constructor with parameters _(String description, String resource, String[] errors, String[] warnings)_ which delegates to super constructor. |
| 75 | +5. Create a method that provides the parameterized test data. (Annotated with _@Parameterized.Parameters_) |
| 76 | +6. Add a test method which delegated to super.test() |
0 commit comments