Issue
I have an annotation processor library that I would like to get working for Kotlin, however I have hit a snag in terms of my unit testing. I would really appreciate if someone could give me some advice.
My current unit testing implementation uses Google's compile-testing library. I create input and output classes and store them in the resources directory. Then during the unit test, the compile-testing library compiles the input java class, executes the annotation processor and then compares the generated classes against the expected output class from the resources directory.
Here is an example (from my project) of what I am referring to: Unit test class Resources (Input and expected output classes
This is working great for all my current java based unit tests. However when I attempt to write some tests using Kotlin classes, my test fails to load the class.
I believe this is due to the compile-testing library being first and foremost a Java specific library (I don't see any mention of Kotlin on their project)
At the moment I get the following issue:
java.lang.IllegalArgumentException: Compilation unit is not of SOURCE kind: "/C:/dev/gsonpath/gsonpath-compiler/build/resources/test/adapter/auto/field_types/primitives/valid/TestValidPrimitives.kt"
at com.sun.tools.javac.api.JavacTool.getTask(JavacTool.java:137)
at com.sun.tools.javac.api.JavacTool.getTask(JavacTool.java:107)
at com.sun.tools.javac.api.JavacTool.getTask(JavacTool.java:64)
at com.google.testing.compile.Compilation.compile(Compilation.java:69)
at com.google.testing.compile.JavaSourcesSubject$CompilationClause.compilesWithoutError(JavaSourcesSubject.java:281)
The problem is fairly obvious that the incorrect compiler is being used. The exception itself is thrown when my file extension is not '.java'. If I attempt to load a Kotlin class with the '.java' file extension, it doesn't work since it is not correct Java syntax.
Has anyone come across this issue before and solved it? I have had a look at a few other annotation processors (such as DBFlow), and they do not write unit tests in this manner.
Since Kotlin is only recently dabbling in annotation processing, perhaps I am the first to have this problem?
Solution
Kotlin integrates with ordinary Java annotation processors by generating "stubs" (empty class carcasses, that have same semantic/methods/fields as target Kotlin classes) [1]. This means, that unit-testing Java annotation processors with kapt
is essentially impossible — even if you somehow integrate the Kotlin tooling in your testing flow, you will end up testing kapt
itself, rather then your own code.
If you want to ensure, that your annotation processing code works with Kotlin-generated stubs, just generate all possible invariants that may be produced by stub generator, and use those as test subjects like any ordinary Java code.
Answered By - user1643723
Answer Checked By - Mary Flores (JavaFixing Volunteer)