是否JUnit4 testclasses需要一个公共的无参数的构造函数?(Does JUnit4 t

2019-07-18 17:00发布

我有一个测试类,写在JUnit4语法,可以在Eclipse中使用“运行方式JUnit测试”选项不会失败运行。 当我通过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)

我没有公开在类无参数的构造函数,但是这真的有必要吗?

这是我的Ant目标

<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>

测试类没有构造函数,但它与默认的修饰符的内部类。 它也有一个anonymouse内部类。 这两个内部类给出了“测试类应该有公共的零参数构造函数的错误”。 我使用的Ant版本1.7.1和JUnit 4.7

Answer 1:

我相信你需要一个无参数的构造函数,但是如果你不声明任何构造函数Java将创建一个合成一个给你。 你肯定蚂蚁任务没有拿起另一个类; 一个正好跟着你设置的命名约定( *TestTest* )?



Answer 2:

您必须对测试用例默认的构造函数。 否则,运动员不知道如何将类实例。 看起来你有ARGS构造。 Java不创建默认的构造函数,如果你已经有一个构造函数。

一般来说,你应该避免在测试用例的构造函数。 如果你想要做初始化,写一个init方法,并用@BeforeClass注释它。 好处是,堆栈跟踪将是干净多了,如果您有任何错误。 正如你可以看到,构造函数的堆栈跟踪让人有些困惑于大多数人。



Answer 3:

Eclipse使用不同的实现来执行JUnit4测试用例 - 它有自己的测试运行。 这恰好是从蚂蚁所使用的不同 - 在JUnit分配可用的默认之一,并且是在蚂蚁和Eclipse的环境中的执行行为注意到差异的原因。

考虑看看的JUnit 4.3.1,4.5和4.7的源代码(尤其是在testrunners的)揭示了测试类必须有一个公共的零参数构造函数。 请注意,在JUnit的V4.7默认亚军是BlockJUnit4ClassRunner 。 你会注意到的javadoc(可惜什么!)包含要遵循什么构成以及形成测试类的规则 - 一个公共无参数的构造函数是其中之一。



Answer 4:

谢谢大家对你的时间和你的答案。 现在我已经找到了解决办法。 以前我以为我的蚂蚁的目标应该是.class文件的batchtest部分的输入,但它也可以使用.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>

现在我唯一的问题是,我有过滤掉的测试类没有测试,以避免出现“没有可运行的方法”误差。 也就是说,助手和UTIL类。

必须有比我更好的解决方案。 一种解决方案可能是一个命名约定的建议[ JUnit的:如何避免在测试utils的课“没有可运行的方法” 。

该助手类不包含@Test annotaion。 它必须能够利用这种以某种方式...



Answer 5:

你的测试类的实例需要以某种方式作出。 您可以创建一个无参数的测试,在增加了一些其他的方式,这可以为参数化的测试有用而创建的测试实例(或在JUnit 3中,反正)。

但是,为什么你会抑制合成的无参数的构造函数?



Answer 6:

有一个无参数的构造函数允许测试类聚合成套件:

 TestSuite suite = new TestSuite();
 suite.add(TestClass.class);
 ...


Answer 7:

对于旧版本的JUnit,如果你在你的内部类有字“测试”,会出现此问题。

我们就遇到了这个问题,同时实现了子类的测试图案,命名的子类,例如,FooForTest。 通过重命名为FooSubclass,问题解决了。

请参阅从@Vineet雷诺兹上述评论有关影响JUnit的版本的更多细节,以及为什么发生这种情况的蚂蚁,但不偏食。

希望帮助!



Answer 8:

非静态内部类有一个隐藏的构造函数外部类作为参数。 如果你的内部类不共享状态与外班,只是让他们static



Answer 9:

可能是因为你使用的Enclosed.class,然后封闭类必须是静态的

@RunWith(Enclosed.class)
public class MyClassThatCointaintTestClasses {
    public static class Class1Test {
@Test
public void test1(){
}
@Test
public void test2(){
}
}

public static class Class2Test {
@Test
public void test21(){
}
@Test
public void test22(){
}
}

}



文章来源: Does JUnit4 testclasses require a public no arg constructor?
标签: java ant junit