JUnit4测试类是否需要public no arg构造函数?

Tho*_*aun 11 java ant junit

我有一个用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

wax*_*ing 8

我相信你需要一个no-args构造函数,但是如果你没有声明任何构造函数,Java将为你创建一个合成构造函数.你确定蚂蚁任务没有进入另一个班级; 恰好遵循您设置(*TestTest*)的命名约定的那个?


ZZ *_*der 5

您必须具有测试用例的默认构造函数.否则,跑步者不知道如何实例化该类.看起来你有一个带args的构造函数.如果您已经有构造函数,Java不会创建默认构造函数.

通常,您应该避免在测试用例中使用构造函数.如果要进行初始化,请编写init方法并使用@BeforeClass进行注释.好处是,如果您有任何错误,堆栈跟踪将更加清晰.正如您所看到的,构造函数的堆栈跟踪对于大多数人来说确实令人困惑.


Vin*_*lds 5

Eclipse使用不同的实现来执行JUnit4测试用例 - 它有自己的测试运行器.这恰好与Ant使用的方法不同 - 这是JUnit发行版中可用的默认方式,也是Ant和Eclipse中环境执行行为中出现差异的原因.

看一下JUnit 4.3.1,4.5和4.7(特别是testrunners的源代码)的源代码,可以看出测试类必须有一个公共的零参数构造函数.请注意,JUnit v4.7中的默认运行程序是BlockJUnit4ClassRunner.你会注意到javadocs(真可惜!)包含了构成格式良好的测试类的规则 - 公共零参数构造函数就是其中之一.


Tho*_*aun 3

感谢大家的宝贵时间和您的回答。我现在已经找到了解决方案。以前我认为 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注释。一定可以以某种方式利用它......