0

We have a wrapper class for checking the Android SDK version, and it uses the ChecksSdkIntAtLeast annotation. Here's a trimmed example of the class with just one getter and the logging removed:

class DeviceApi( private val deviceOsVersion: Int ) { @get:ChecksSdkIntAtLeast(api = Build.VERSION_CODES.M) val isApi23AndAbove get() = deviceOsVersion >= Build.VERSION_CODES.M } 

We have tests for the getter itself, but I was hoping to write tests to verify that the getter also has the annotation in place with the correct value, to avoid the compiler warnings that show up if it isn't included. However, no matter what I try, I can't seem to find the annotation via reflection.

Here's two basic examples that work if I do this for a Kotlin annotation class annotation that just don't find the public @interface annotations provided by androidx.annotation:

@Test fun kotlin_reflection_example() { assertThat(DeviceApi::isApi23AndAbove.getter.hasAnnotation<ChecksSdkIntAtLeast>()).isTrue } @Test fun java_reflection_example() { assertThat(DeviceApi::isApi23AndAbove.javaGetter!!.getAnnotation(ChecksSdkIntAtLeast::class.java)).isNotNull } 

I've also tried various examples I've seen online for looking for members and methods from the class and debugged to inspect the state of various things, but I've been unable to get any of the code to see the annotation. I want to know if I'm missing something obvious or if I found a scenario that just isn't supported by kotlin-reflect - and if so, if there's an alternative.

6
  • 2
    That annotation is not retained at runtime. That’s why you can’t find it. How about using your own annotation? Commented Jul 28, 2023 at 10:32
  • @Sweeper ah, that would explain it, thanks. I don't think writing my own would add anything in this particular scenario, unless I can also get the compiler to treat it the same was as the original does - otherwise it's just extra fluff for a test with no real functionality. If you know of a way to make it testable and functionally similar I'd love to hear more though. Commented Jul 28, 2023 at 10:49
  • hasAnnotation and getAnnotation should really just throw an exception if the annotation doesn't have the correct retention type. Would save so much trouble. Commented Jul 28, 2023 at 10:57
  • After the comment by @Sweeper I've been able to retain the functionality and add visibility by creating a copy of the in my project with package androidx.annotation at the top to override the original and @Retention(AnnotationRetention.RUNTIME) on the class to ensure tests can see it. This feels extremely hacky to me though, so I'm holding off on answering my own question with it as a solution in the hope that someone can think of a neater way of doing it. Commented Jul 28, 2023 at 11:16
  • 1
    You can process your own annotation by generating the built-in annotation using an annotation processor. See here for a start. Commented Jul 28, 2023 at 11:19

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.