y
08/17/2024, 2:52 PMsealed class MyError
. in my unit tests, I have code that checks a list of `MyError`s produced by some other source.
for some error, I'd like to assert that the error is an instance is of a specific subclass, say MyError.Foo
data class AcceptsSpecificError {
fun check(e: MyError) {
// assert that `e` has type `MyError.Foo`
}
}
how can I do this?
I can't make this AcceptsSpecificError<T: MyError>
because of type erasure.
also it's not feasible for AcceptsSpecificError
to take a val e: MyError
and then compare to that, because some of the subclasses of MyError
are too complex to easily instantiate in a unit test environment.
EDIT: would taking a property of type KClass<T: MyError>
work here? what I really want here is a "phantom data" kind of value I can take so that T
is not type erased.Jack Boswell
08/17/2024, 3:14 PMassertTrue(e is MyError.Foo)
y
08/17/2024, 3:16 PMAcceptsSpecificError<Foo.Bar>().check(e)
.
I got this to work by adding a property of type KClass
. which, after searching around, seems to be what I'm supposed to do here.Daniel Pitts
08/17/2024, 7:14 PMimport kotlin.reflect.KClass
sealed class MyError {
data object Foo : MyError()
data object Bar : MyError()
}
class AcceptsSpecificError<T : MyError>(val type: KClass<T>) {
fun check(e: MyError) {
check(type.isInstance(e)) { "Expected $type, got ${e::class}" }
}
}
inline fun <reified T : MyError> AcceptsSpecificError() = AcceptsSpecificError(T::class)
y
08/18/2024, 4:23 PMy
08/18/2024, 4:32 PMinline fun
is not allowed to access a non-public constructorDaniel Pitts
08/18/2024, 4:33 PMDaniel Pitts
08/18/2024, 4:34 PMclass AcceptsSpecificError<T : MyError> @PublishedApi internal constructor(val type: KClass<T>) {
Daniel Pitts
08/18/2024, 4:36 PMDaniel Pitts
08/18/2024, 4:37 PMKClass<T>
themselves, even if they aren't in a context where they have a reified type T
.y
08/18/2024, 4:39 PMDaniel Pitts
08/18/2024, 4:40 PM