如何在Java编译时链接异常类

时间:2014-04-07 13:56:05

标签: java unit-testing exception-handling testng

作为使用Java进行面向对象编程的一部分,我们进行了大量(20-36小时)的实践练习 - 今年基于俄罗斯方块。学生们按照指南解释 - 通过文本描述和uml类图 - 如何实现他们的游戏。连接到本指南的工具是运行一系列单元测试(使用TestNg编写)来检查其实现是否符合指令。单元测试使用100%符合版本的代码进行预编译,并通过自定义用户界面启动,该界面显示测试结果。执行的测试数量取决于学生已达到的部分。

单元测试类的结构都是类似的:

public static void classExists(String fullClassName) {
    try {
        @SuppressWarnings("unused")
        Class<?> clazz = Class.forName(fullClassName);
    } catch (ClassNotFoundException cnfe) {
        fail(fullClassName + " could not be found on the classpath.");
    }
}
  1. 测试类是否存在

  2. 如果(1)成功:测试班级可见性

  3. 如果(2)成功:测试方法/属性是否存在

  4. 如果(3)成功:测试方法的功能

  5. 这样做很有效,除了扩展Exception的类,如果我们在测试时(4)我们写:

    BloxException be = new BloxException("Message",value);
    

    测试按预期工作,特别是如果BloxException不存在,test(1)失败并且其他测试没有执行,但是如果我们尝试抛出异常:

    throw new BloxException("Message", value);
    

    测试未执行,因为TestNg无法找到类BloxException。 我们假设这是由于Java如何编译上面的两行,可以任何人给我详细说明为什么当我们抛出异常时我们需要类,但是如果我们创建一个新的异常,我们不需要代码来执行测试

    这是Exception StackTrace,仅在使用throw new BloxException时发生:

    java.lang.NoClassDefFoundError: fr/eseo/blox/model/BloxException
    at java.lang.Class.getDeclaredMethods0(Native Method)
    at java.lang.Class.privateGetDeclaredMethods(Class.java:2436)
    at java.lang.Class.privateGetPublicMethods(Class.java:2556)
    at java.lang.Class.getMethods(Class.java:1412)
    at org.testng.internal.TestNGClassFinder.<init>(TestNGClassFinder.java:59)
    at org.testng.TestRunner.initMethods(TestRunner.java:409)
    at org.testng.TestRunner.init(TestRunner.java:235)
    at org.testng.TestRunner.init(TestRunner.java:205)
    at org.testng.TestRunner.<init>(TestRunner.java:153)
    at org.testng.SuiteRunner$DefaultTestRunnerFactory.newTestRunner(SuiteRunner.java:522)
    at org.testng.SuiteRunner.init(SuiteRunner.java:157)
    at org.testng.SuiteRunner.<init>(SuiteRunner.java:111)
    at org.testng.TestNG.createSuiteRunner(TestNG.java:1273)
    at org.testng.TestNG.createSuiteRunners(TestNG.java:1260)
    at org.testng.TestNG.runSuitesLocally(TestNG.java:1114)
    at org.testng.TestNG.run(TestNG.java:1031)
    at fr.eseo.ac20.core.validation.runners.Validator.<init>(Validator.java:131)
    at fr.eseo.ac20.core.validation.runners.CustomValidator.<init>(CustomValidator.java:21)
    at fr.eseo.ac20.core.validation.runners.CustomValidator.main(CustomValidator.java:17)
    Caused by: java.lang.ClassNotFoundException: fr.eseo.blox.model.BloxException
        at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
        ... 19 more
    

    作为帮助,我创建了两个简单的测试用例来显示正在发生的事情,可以从examples.zip下载它们。解压缩文件并从命令行更改到tng_good文件夹并执行

    java -cp testng-6.0.1.jar:. org.testng.TestNG tng.xml
    

    然后转到tng_bad文件夹并执行相同的

    java -cp testng-6.0.1.jar:. org.testng.TestNG tng.xml
    

    第一个执行,存在测试失败,第二个给出异常。 (测试方法的代码源位于示例子文件夹中)

1 个答案:

答案 0 :(得分:0)

这与此异常无关。这里的问题在于您加载代码的方式。

在第一种情况下,请致电

Class.forName(fullClassName);

对于不可用的类,您将获得ClassNotFoundException,并且不会加载该类。

在第二种情况下,TestNG TestRunner类加载了一个依赖于另一个不可用的类的类。稍后它会尝试获取方法的类型信息......由于缺少依赖性而失败。由于JVM现在告诉应用程序关于缺少依赖关系的类,它现在处于该类被“破坏”的状态。因此,它会抛出不同的异常NoClassDefFoundError


基本上,您单独加载和测试类的想法是行不通的。当你加载一个类时,它所依赖的任何类(包括它抛出的任何异常)都需要加载......否则你将获得异常。

  

他们不应该运行它,但学生是学生,他们有时会尝试运行所有测试,即使他们没有完成该部分。

易。向他们解释如果他们这样做将不起作用: - )