作为使用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)成功:测试方法/属性是否存在
如果(3)成功:测试方法的功能
这样做很有效,除了扩展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
第一个执行,存在测试失败,第二个给出异常。 (测试方法的代码源位于示例子文件夹中)
答案 0 :(得分:0)
这与此异常无关。这里的问题在于您加载代码的方式。
在第一种情况下,请致电
Class.forName(fullClassName);
对于不可用的类,您将获得ClassNotFoundException
,并且不会加载该类。
在第二种情况下,TestNG TestRunner
类加载了一个依赖于另一个不可用的类的类。稍后它会尝试获取方法的类型信息......由于缺少依赖性而失败。由于JVM现在告诉应用程序关于缺少依赖关系的类,它现在处于该类被“破坏”的状态。因此,它会抛出不同的异常NoClassDefFoundError
。
基本上,您单独加载和测试类的想法是行不通的。当你加载一个类时,它所依赖的任何类(包括它抛出的任何异常)都需要加载......否则你将获得异常。
他们不应该运行它,但学生是学生,他们有时会尝试运行所有测试,即使他们没有完成该部分。
易。向他们解释如果他们这样做将不起作用: - )