使用IntelliJ在kotlin gradle项目中调试单元测试时,为什么会有几十个无意义的异常?

时间:2018-03-08 18:31:48

标签: gradle intellij-idea kotlin

我上传了一个trivially-simple test project to gitlab,其中包含两个kotlin文件。

Trivial.kt有一个简单的类:

package com.example
class Trivial {
    fun gus() {
        error("Behold my erroneousness!")
    }
}

TrivialTests.kt有一个简单的测试:

package com.example
import org.junit.Test
class TrivialTests {
    @Test
    fun testGus() {
        val din = Trivial()
        din.gus()
    }
}

build.gradle文件执行apply plugin: 'kotlin'并列出了常用的依赖项:

dependencies {
  compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
  compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"

  testCompile 'junit:junit:4.12'
  testCompile "org.jetbrains.kotlin:kotlin-test:$kotlin_version"
}

而且,在gradle本身,这一切都完全符合您的期望。我的./gradlew test电话上IllegalStateException死于error。但是,现在我想使用IntelliJ调试失败的测试。所以我使用IntelliJ' s"导入项目"特征。完成后,行号与测试函数的开头之间会出现绿色箭头,右键单击它会为我提供调试测试的选项。选择该选项会调出调试器,并立即运行并使测试失败。

我想在异常时自动中断,所以我在断点窗口中检查"任何异常"的启用按钮,然后尝试再次开始测试。我立即被带到了类加载器,它为ClassNotFoundException抛出"org.groovy.debug.hotswap.ResetAgent"。我点击继续,我得到另一个ClassNotFoundException,这比我可以计算的次数多。大多数例外都是关于org.junit类,偶尔会混合使用kotlin和gradle类。

使用class filter,我从断点中排除从*ClassLoader引发的异常,然后继续。下一站是java.lang.Integer,这引发了一个数字格式异常,因为intellij本身试图调用Integer.parseInt("java/util/concurrent/CompletableFuture$UniRun")。它使用不同的类型名称多次执行此操作,然后是JUnit的转向,尝试打开属性文件获得FileNotFoundException以及一堆不打开的罐子存在。

在许多相同项目中与我合作的同事坚持认为他从未见过这些例外情况,这表明我的配置存在问题,但我找不到任何问题。 intellij设置似乎影响结果。

我可以通过将我的软件包列入白名单来获得我想要的调试行为 - 添加通配符类过滤器以仅包含com.example*

问题是:为什么junit首次启动时会出现如此多的令人讨厌的异常?

1 个答案:

答案 0 :(得分:0)

正如@Strelok在评论中所暗示的那样,代码没有任何问题,并且当JUnit启动时被各种内部组件抛出的无用异常的动物只是其初始化的正常部分。

我的同事从未见过这些例外情况,因为他有过#" Caught Exceptions"在他的异常断点UI中取消选中。这里的问题是IntelliJ没有特殊情况JUnit,而JUnit捕获了测试中发生的所有异常,因此取消选中该选项会导致测试失败,而不会在断点处停止。

Hans-Peter Störrthis answer提供了针对此问题的更好的解决方法:

  

"任何例外"使用catch类过滤器org.junit.runners。*和类过滤器-org.junit。*来解决捕获和未捕获异常的断点,以消除JUnit机制本身抛出的捕获异常。

不幸的是,似乎没有办法使其成为默认值,因此必须为每个intellij项目完成,但它确实导致调试器仅在我的代码中的未处理异常处停止。 / p>