Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/ant/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/webpack/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JUnit4测试类是否需要公共的无参数构造函数?_Java_Ant_Junit - Fatal编程技术网

Java JUnit4测试类是否需要公共的无参数构造函数?

Java JUnit4测试类是否需要公共的无参数构造函数?,java,ant,junit,Java,Ant,Junit,我有一个用JUnit4语法编写的测试类,它可以在eclipse中使用“RunasJUnitTest”选项运行而不会失败。当我通过ant目标运行相同的测试时,我得到以下错误: java.lang.Exception: Test class should have public zero-argument constructor at org.junit.internal.runners.MethodValidator.validateNoArgConstructor(MethodValidator

我有一个用JUnit4语法编写的测试类,它可以在eclipse中使用“RunasJUnitTest”选项运行而不会失败。当我通过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)
java.lang.Exception:测试类应具有公共零参数构造函数
位于org.junit.internal.runners.MethodValidator.validateNoArgConstructor(MethodValidator.java:54)
位于org.junit.internal.runners.MethodValidator.validateAllMethods(MethodValidator.java:39)
位于org.junit.internal.runners.TestClassRunner.validate(TestClassRunner.java:33)
位于org.junit.internal.runners.TestClassRunner。(TestClassRunner.java:27)
位于org.junit.internal.runners.TestClassRunner。(TestClassRunner.java:20)
位于sun.reflect.NativeConstructorAccessorImpl.newInstance0(本机方法)
位于sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
在sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
位于java.lang.reflect.Constructor.newInstance(Constructor.java:513)
位于org.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:26)
位于junit.framework.JUnit4TestAdapter。(JUnit4TestAdapter.java:24)
位于junit.framework.JUnit4TestAdapter。(JUnit4TestAdapter.java:17)
位于sun.reflect.NativeConstructorAccessorImpl.newInstance0(本机方法)
位于sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
在sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
位于java.lang.reflect.Constructor.newInstance(Constructor.java:513)
位于org.apache.tools.ant.taskdefs.optional.junit.junitestrunner.run(junitestrunner.java:386)
位于org.apache.tools.ant.taskdefs.optional.junit.junitestrunner.launch(junitestrunner.java:911)
位于org.apache.tools.ant.taskdefs.optional.junit.junitestrunner.main(junitestrunner.java:768)
原因:java.lang.NoSuchMethodException:dk.gensam.gaia.business.bonusregulering.TestBonusregulerAftale$Test1Reader.()
位于java.lang.Class.getConstructor0(Class.java:2706)
位于java.lang.Class.getConstructor(Class.java:1657)
位于org.junit.internal.runners.MethodValidator.validateNoArgConstructor(MethodValidator.java:52)
我在类中没有公共的无参数构造函数,但是这真的是必要的吗

这是我的蚂蚁目标

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


测试类没有构造函数,但它有一个带有默认修饰符的内部类。它还有一个匿名的内部类。两个内部类都给出了“测试类应该有公共零参数构造函数错误”。我正在使用Ant版本1.7.1和JUnit 4.7,您的测试类的实例需要以某种方式生成。您可以创建一个无参数测试,它添加以其他方式创建的测试实例,这对于参数化测试很有用(或者在JUnit3中也是如此)


但是为什么要禁止使用合成的无参数构造函数呢?

使用无参数构造函数可以将测试类聚合到套件中:

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

我相信您需要一个无参数构造函数,但如果您不声明任何构造函数,Java将为您创建一个合成构造函数。您确定ant任务没有拾取其他类;恰好遵循您设置的命名约定(
*Test
Test*
)的一个实例?

您必须为测试用例设置一个默认构造函数。否则,运行程序不知道如何实例化该类。看起来您有一个带args的构造函数。如果已经有构造函数,Java不会创建默认构造函数


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

Eclipse使用不同的实现来执行JUnit4测试用例——它有自己的测试运行程序。这恰好与Ant使用的不同,Ant使用的是JUnit发行版中的默认版本,这也是Ant和Eclipse中环境的执行行为出现差异的原因


查看JUnit4.3.1、4.5和4.7的源代码(特别是TestRunner的源代码)可以发现,测试类必须有一个公共的零参数构造函数。请注意,JUnit v4.7中的默认运行程序是。您会注意到,javadocs(真遗憾!)包含了构成良好格式测试类的规则——公共零参数构造函数就是其中之一。

感谢大家的时间和回答。 我现在找到了解决办法。以前我认为ant目标的batchtest部分的输入应该是.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>

我现在唯一的问题是,我必须过滤掉没有测试的测试类,以避免出现“无法运行的方法”错误。即helper和util类

一定有比我更优雅的解决方案。一种解决方案可以是建议的命名约定[


helper类不包含@Test注释。必须能够以某种方式利用它…

非静态内部类有一个以外部类为参数的隐藏构造函数。如果您的内部类不与外部类共享状态,只需将其设置为较旧版本的
静态

@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(){
}
}