我有一个用JUnit4语法编写的测试类,它可以在eclipse中使用"run as junit test"选项运行而不会失败.当我通过ant目标运行相同的测试时,我收到此错误:
java.lang.Exception: Test class should have public zero-argument constructor
at org.junit.internal.runners.MethodValidator.validateNoArgConstructor(MethodValidator.java:54)
at org.junit.internal.runners.MethodValidator.validateAllMethods(MethodValidator.java:39)
at org.junit.internal.runners.TestClassRunner.validate(TestClassRunner.java:33)
at org.junit.internal.runners.TestClassRunner.<init>(TestClassRunner.java:27)
at org.junit.internal.runners.TestClassRunner.<init>(TestClassRunner.java:20)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at org.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:26)
at junit.framework.JUnit4TestAdapter.<init>(JUnit4TestAdapter.java:24)
at junit.framework.JUnit4TestAdapter.<init>(JUnit4TestAdapter.java:17)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.run(JUnitTestRunner.java:386)
at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.launch(JUnitTestRunner.java:911)
at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.main(JUnitTestRunner.java:768)
Caused by: java.lang.NoSuchMethodException: dk.gensam.gaia.business.bonusregulering.TestBonusregulerAftale$Test1Reader.<init>()
at java.lang.Class.getConstructor0(Class.java:2706)
at java.lang.Class.getConstructor(Class.java:1657)
at org.junit.internal.runners.MethodValidator.validateNoArgConstructor(MethodValidator.java:52)
Run Code Online (Sandbox Code Playgroud)
我在课堂上没有公开的arg构造函数,但这真的有必要吗?
这是我的蚂蚁目标
<target name="junit" description="Execute unit tests" depends="compile, jar-test">
<delete dir="tmp/rawtestoutput"/>
<delete dir="test-reports"/>
<mkdir dir="tmp/rawtestoutput"/>
<junit printsummary="true" failureproperty="junit.failure" fork="true">
<classpath refid="class.path.test"/>
<classpath refid="class.path.model"/>
<classpath refid="class.path.gui"/>
<classpath refid="class.path.jfreereport"/>
<classpath path="tmp/${test.jar}"></classpath>
<batchtest todir="tmp/rawtestoutput">
<fileset dir="${build}/test">
<include name="**/*Test.class" />
<include name="**/Test*.class" />
</fileset>
</batchtest>
</junit>
<junitreport todir="tmp">
<fileset dir="tmp/rawtestoutput"/>
<report todir="test-reports"/>
</junitreport>
<fail if="junit.
failure" message="Unit test(s) failed. See reports!"/>
</target>
Run Code Online (Sandbox Code Playgroud)
测试类没有构造函数,但它有一个带有默认修饰符的内部类.它也有一个匿名内部类.两个内部类都给出了"测试类应该具有公共零参数构造函数错误".我正在使用Ant版本1.7.1和JUnit 4.7
我相信你需要一个no-args构造函数,但是如果你没有声明任何构造函数,Java将为你创建一个合成构造函数.你确定蚂蚁任务没有进入另一个班级; 恰好遵循您设置(*Test或Test*)的命名约定的那个?
您必须具有测试用例的默认构造函数.否则,跑步者不知道如何实例化该类.看起来你有一个带args的构造函数.如果您已经有构造函数,Java不会创建默认构造函数.
通常,您应该避免在测试用例中使用构造函数.如果要进行初始化,请编写init方法并使用@BeforeClass进行注释.好处是,如果您有任何错误,堆栈跟踪将更加清晰.正如您所看到的,构造函数的堆栈跟踪对于大多数人来说确实令人困惑.
Eclipse使用不同的实现来执行JUnit4测试用例 - 它有自己的测试运行器.这恰好与Ant使用的方法不同 - 这是JUnit发行版中可用的默认方式,也是Ant和Eclipse中环境执行行为中出现差异的原因.
看一下JUnit 4.3.1,4.5和4.7(特别是testrunners的源代码)的源代码,可以看出测试类必须有一个公共的零参数构造函数.请注意,JUnit v4.7中的默认运行程序是BlockJUnit4ClassRunner.你会注意到javadocs(真可惜!)包含了构成格式良好的测试类的规则 - 公共零参数构造函数就是其中之一.
感谢大家的宝贵时间和您的回答。我现在已经找到了解决方案。以前我认为 ant 目标的批量测试部分的输入应该是 .class 文件,但也可以使用 .java 文件。
这解决了问题。现在它不再抱怨内部类缺少公共构造函数。
<target name="junit" description="Execute unit tests">
<delete dir="tmp/rawtestoutput"/>
<delete dir="test-reports"/>
<mkdir dir="tmp/rawtestoutput"/>
<junit printsummary="on" failureproperty="junit.failure" fork="true">
<jvmarg value="-Duser=TBA -Dpassword=ibber11"/>
<classpath refid="class.path.test"/>
<classpath refid="class.path.model"/>
<classpath refid="class.path.gui"/>
<classpath refid="class.path.jfreereport"/>
<classpath path="tmp/${test.jar}"/>
<batchtest todir="tmp/rawtestoutput">
<fileset dir="src/test">
<include name="**/*.java"/>
<exclude name="**/SessionHelper.java"/>
<exclude name="**/TestHelper.java"/>
</fileset>
</batchtest>
<sysproperty key="user" value="tba"/>
<sysproperty key="password" value="ibber11"/>
</junit>
<junitreport todir="tmp">
<fileset dir="tmp/rawtestoutput"/>
<report todir="test-reports"/>
</junitreport>
<fail if="junit.failure" message="Unit test(s) failed. See reports!"/>
</target>
Run Code Online (Sandbox Code Playgroud)
我现在唯一的问题是,我必须过滤掉没有测试的测试类,以避免“没有可运行的方法”错误。即 helper 类和 util 类。
一定有比我更优雅的解决方案。一种解决方案可能是建议的命名约定[ JUnit:如何避免测试实用程序类中的“不可运行的方法”。
帮助器类不包含@Test注释。一定可以以某种方式利用它......