【发布时间】:2014-05-19 19:44:49
【问题描述】:
作为介绍使用 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 不存在,测试 (1) 失败并且其他测试没有执行,但是如果我们尝试抛出异常:
throw new BloxException("Message", value);
测试未执行,因为 TestNg 找不到类 BloxException。 我们假设这是由于Java如何编译上面的两行代码,谁能给我详细说明为什么当我们抛出异常时我们需要类,但是如果我们创建一个新的异常,我们不需要代码来执行测试?
这是仅在使用 throw new BloxException 时发生的异常 StackTrace:
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
第一个执行,exists 测试失败,第二个给出异常。 (测试方法的代码源在 example 子文件夹中)
【问题讨论】:
-
这几乎没有意义。无论您是否
throw异常,您都有完全相同的实例创建表达式,无论上下文如何,它的计算结果都完全相同。 -
向我们展示来自 TestNg 的堆栈跟踪,显示您正在谈论的行为。
-
我不认为这是异常的特殊之处。您确定类文件在正确的位置,并且在任何需要的地方都输入了正确的名称?
-
Marko,我完全同意你的看法,但是当我尝试抛出一个新的异常时,我得到一个类不存在的异常(来自 TestNg 和我的跑步者类),但是当我刚刚实例化该类,执行我的第一个测试并停止测试(跳过最后一个测试)。
-
如果他们没有这个类,你希望他们如何运行它?
标签: java unit-testing exception-handling testng