11

I'm having some problems when defining inner classes in a Test class inherited from TestCase, for JUnit 3. Scenario is like following:

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

Now, if I run this from Eclipse, the tests run ok, but if I try to run from an Ant task it fails:

[junit] junit.framework.AssertionFailedError: Class Foo$Bar has no public constructor TestCase(String name) or TestCase()

Bar is NOT a Test class, it's just a subclass of Foo overriding some method that I don't need to do the real stuff when testing.

I'm quite lost at the moment and I don't know how to approach this problem. Is the only way to create the subclasses as standalone?

Gothmog
  • 871
  • 1
  • 8
  • 20

4 Answers4

19

This is because you included a nested class into junit fileset. Add an "excludes" property to your build.xml.

For example:

<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>  
Kai Zhang
  • 1,028
  • 8
  • 9
  • This is actually a better solution than @Ignore, as the inner classes does not show up at all in test results files when they're excluded in build.xml. Both solutions work though. – joscarsson Aug 07 '12 at 11:00
  • Thanks for this answer, you helped me understand why ant's junit test was barfing just because I have a private inner class. The exclude statement did the trick. – JulianHarty Mar 05 '13 at 20:17
  • I happen to be using a `` with a nested `` with a `refid`. You can't change the `` but you can still put an `` element inside the `` to remove the inner classes that the `` would have included. – Christopher Schultz Feb 28 '18 at 22:35
5

You could try defining the Bar class as static:

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

... but the fact that it works in one environment but not in another suggests one of two things:

  1. Java version
  2. Classpath
  3. [Edit: as suggested by Jim below] Different versions of junit.jar
Jason
  • 11,744
  • 3
  • 42
  • 46
  • 1
    +1 I'd add one more: different versions of junit.jar. It's possible an older version of JUnit is confused by the nested non-static class. – Jim Garrison Nov 11 '10 at 03:29
4

You can also annotate the nested class @Ignore if you don't want to exclude all inner classes.

Roth Michaels
  • 348
  • 1
  • 6
4

I'm feeling like a necrposter, but the thing is that I've ran into similar problem with maven today.

Usual mvn test runs well but when I want run tests from specific package like mvn test -Dtest=com.test.* - initializationError is thrown. This "works" for both Junit 3 and 4.

I found the reason for my maven-case, this may be the same for ant. The thing is: by default maven's test plugin (surefire that is) considers only specific subset of all classes as "test-classes", namely searching them by name, like *Test and so on (you can read about this at surefire's home page).When we define test property we completely override default behavior. This means that with -Dtest=com.test.* surefire will pick up not only com.test.MyTestClass but also com.test.MyTestClass.InnerClass and even com.test.MyTestClass$1 (i.e. anonymous classes).

So in order to run e.g. classes from some package you should use something like -Dtest=com.test.*Test (if you use suffixes for identifying test-classes of course).

yozh
  • 1,213
  • 2
  • 10
  • 18