例如,我想编写一个测试,该测试应捕获Exception的特定子类。 为此,我写
fun test(klazz: KClass<in Exception>) {
try {
...
} catch (e: Exception) {
if (!kclazz.isInstance(e)) {
throw e
} else {
...
}
}
}
有没有一种更简单的方法可以做到这一点?因为在这种情况下我不希望添加额外的类检查,而只是进一步抛出捕获的异常是一个很好的解决方案。有什么类似下面的代码?
fun test(klazz: KClass<in Exception>) {
try {
...
} catch (e: klazz(smth here)) {
...
}
}
我几乎可以肯定没有,因为我尝试了许多不同的方法。但是在这种情况下,如果有人可以解释为什么不可能的话,那将很酷。
答案 0 :(得分:0)
不可能,因为语法
catchBlock
(used by tryExpression)
: 'catch' '(' annotation* simpleIdentifier ':' type ')' block
;
requires a type
in that position,并且类型无法依赖klazz
(在Kotlin中)之类的值。
我尝试了
inline fun <reified E : Exception> test() {
try {
...
} catch (e: E) {
...
}
}
,但这是专门排除的apparently because it didn't work properly when it wasn't。当然了
} catch (e: Exception) {
if (e is E) ...
}
确实有效,并且可能比通过KClass
更好。
答案 1 :(得分:0)
我使用此高级实用程序功能做了类似的事情:
/**
* Asserts that the given block of code throws an exception of the specified type.
*
* This is much more fine-grained than `@Test(expected = ...)`, letting
* you check that the exception was thrown by specific line(s) of code.
*
* @return The exception thrown. This lets you make further tests on it
* (e.g. in an `also{}` block).
* @throws AssertionError if no exception, or one of another type, was thrown.
*/
inline fun <reified T: Exception> assertThrows(exceptionClass: KClass<T> = T::class, block: () -> Unit): T {
try {
block()
throw AssertionError("Should have thrown ${exceptionClass.simpleName}!")
} catch (x: Exception) {
if (x is T)
return x
throw AssertionError("Should have thrown ${exceptionClass.simpleName}, but threw $x!")
}
}
您可以在单元测试中使用它,例如:
@Test fun myTest() {
assertThrows(NullPointerException::class) {
// Some code that should throw a NullPointerException...
}
}
(虽然不止一行,但还是很简洁,而且读起来不错。)