Recently, I was writing an Annotation Processor for the @Composite project. In good TDD fashion, that first and foremost meant writing some tests. Although I in the end come across something that was fairly workable, it was trickier than one might have hoped for. The javax.lang.model API consists almost entirely of interfaces. Predestined for mocking, one might say. But unfortunately, after a couple of abortive attempts I was forced to realize that there is unfortunately no convenient way of converting segments of code to test into their model API representation. Well, I should say almost no convenient way. Thankfully, there's one old friend one can always turn to for such transformations...javac. What, Runtime.exec? With all the system-dependent brittleness that brings? Violating the holy principle of platform a test?? Well, luckily this is Java 6, so none of that is necessary. The compiler API comes to our rescue. Of course, invoking the compiler means compiling entire classes, as opposed to code snippets, and only allows us to test the annotation processor as a whole. If you've modularized your annotation processor, these are really integration rather than unit tests. But since you control the source that is being compiled, it should be easy to come up with examples that test individual parts of the processor's functionality. Slightly more inconvenient is the fact that this approach the only allows code paths to be tested that influence the result of the compilation, e.g. by throwing an error or raising a warning, or produce some side effect, e.g. by writing (to) a file. Any "internal" logic that does neither of these is not verifiable in this manner. Further, when checking for the expected result of the compilation, "there should be one error" usually isn't enough. For instance, in the case of this validation processor, I would like to be sure that the error returned really is caused by the code that is in error, not by a bug in the processor which accepts the wrong code but mistakenly reports an error elsewhere. Since checking for error messages is horrifically brittle, the best one can do here appears to be to expect errors at a specific location, i.e. line of code. This is marginally better and seems to work, but still smells rather fishy. In code Enough talk. Here's a code sample: public class CompositeAnnotationValidationProcessorTest extends AbstractAnnotationProcessorTest { @Override protected Collection getProcessors() { return Arrays. asList(new CompositeAnnotationValidationProcessor()); } @Test public void leafAnnotationOnNonCompositeMember() { assertCompilationReturned(Kind.ERROR, 22, compileTestCase(InvalidLeafAnnotationUsage.class)); } @Test public void validCompositeAnnotation() { assertCompilationSuccessful(compileTestCase(ValidCompositeAnnotation.class)); } } Here, getProcessors returns the annotation processor instances that are supposed to be called during the compilation. The first test expects the compilation of the InvalidLeafAnnotationUsage class to return an error in line 22, whilst the second expects the compilation of ValidCompositeAnnotation to be successful, i.e. contain no errors3. For details see the original post.