在JUnit的测试类中定义内部类时出现错误

11
我在从TestCase继承的Test类中定义内部类时遇到了一些问题,对于JUnit 3,情况如下:

Foo.java

public class Foo {
  public void method() { ... }
}

FooTest.java

public class FooTest extends TestCase {
  public class Bar extends Foo {
    public void method() { ... }
  }
  public void testMethod() { ... }
}

现在,如果我从Eclipse中运行这个测试,测试就可以正常运行,但是如果我尝试从一个Ant任务中运行它,测试就会失败:

[junit] junit.framework.AssertionFailedError: Class Foo$Bar没有公共的构造函数TestCase(String name)或TestCase()

Bar不是一个测试类,它只是Foo的子类,重写了一些我在测试时不需要实际执行的方法。

我现在很迷茫,不知道如何解决这个问题。是否唯一的方法是将子类创建为独立的类?


你的Ant配置用于运行测试是什么? - matt b
4个回答

19

这是因为您在junit文件集中包含了一个嵌套类。 请在您的build.xml文件中添加一个“excludes”属性。

例如:

<target name="test" depends="test-compile">
    <junit>
        <batchtest todir="${test.build.dir}" unless="testcase">
            <fileset dir="${test.build.classes}"
                includes = "**/Test*.class"
                excludes = "**/*$*.class"/>
        </batchtest>
    </junit>
</target>  

这实际上比@Ignore更好的解决方案,因为当在build.xml中排除内部类时,测试结果文件中根本不会显示它们。但两种解决方案都可以工作。 - joscarsson
谢谢你的回答,你帮我理解了为什么Ant的JUnit测试会因为我有一个私有内部类而出错。排除语句解决了这个问题。 - JulianHarty
我恰好正在使用一个带有嵌套的<patternset>refid<fileset>。您无法更改<patternset>,但仍可以在<fileset>中放置一个<exclude name="**/*$*.class" />元素,以删除<patternset>将包含的内部类。 - Christopher Schultz

5
你可以尝试将Bar类定义为静态的:
``` 你可以尝试将Bar类定义为静态的: ```
public class FooTest extends TestCase {
  public static class Bar extends Foo {
    public void method() { ... }
  }
  public void testMethod() { ... }
}

......但它在一个环境中工作而在另一个环境中不工作的事实表明两件事之一:

  1. Java版本
  2. 类路径
  3. [编辑:如Jim下面所建议的] junit.jar的不同版本

1
我想再多加一点:不同版本的junit.jar文件。可能旧版的JUnit会被嵌套的非静态类所混淆。 - Jim Garrison

4
如果您不想排除所有内部类,您还可以注释嵌套类@Ignore。

1
这对于匿名内部类无效。@Ignore注释在此处无效。 - Fabian Barney
1
是的,但问题不是关于匿名内部类的。 - Roth Michaels

4

我感觉像一个死灵法师,但今天我遇到了与Maven相关的类似问题。

通常的mvn test运行良好,但当我想要从特定包中运行测试,例如mvn test -Dtest=com.test.*时,会抛出initializationError。无论是Junit 3还是4都会出现这种情况。

我找到了我的Maven案例的原因,这可能也适用于Ant。问题是:默认情况下,Maven的测试插件(即Surefire)仅将所有类的特定子集视为“测试类”,即按名称搜索它们,例如*Test等(您可以在Surefire主页上阅读有关此内容的更多信息)。当我们定义test属性时,我们完全覆盖了默认行为。这意味着使用-Dtest=com.test.*,Surefire不仅会选择com.test.MyTestClass,还会选择com.test.MyTestClass.InnerClass甚至是匿名类com.test.MyTestClass$1

因此,为了运行来自某个包中的类,您应该使用类似于-Dtest=com.test.*Test的内容(如果您使用后缀来标识测试类的话)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接