Why @RunWith accepts KClass but willThrow() doesn't?


#1

Hello,

While writting a unit test, I came across a question :

The annotation @RunWith is defined in Java and it accepts a Class as its value:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Inherited
public @interface RunWith {
    /**
     * @return a Runner class (must have a constructor that takes a single Class to run)
     */
    Class<? extends Runner> value();
}

The method willThrow() from DDMockito also takes as its only argument a Class.

BDDMyOngoingStubbing<T> willThrow(Class<? extends Throwable> throwableType);

However, in a Kotlin file, I can write @RunWith(ARunner::class) but i can’t write .willThrow(AnException::class), I have to explicitly write .willThrow(AnException::class.java).

Is there some sort of sugar that automagically convert KClass to Class when used as annotation parameters ?
Why can’t it be the same for KClass given as arguments to java-defined method accepting Class ?

Thank you for your answer !
Pierre


#2

Yes.

If you need to specify a class as an argument of an annotation, use a Kotlin class (KClass). The Kotlin compiler will automatically convert it to a Java class, so that the Java code will be able to see the annotations and arguments normally.

In normal code such magic would complicate things and might lead to unexpected results. Kotlin doesn’t support automatic type conversion in code.


#3

Thanks Jonathan.


#4

You can probably write an extension method to allow kclass parameters.