如何在不将方法设为静态

时间:2015-07-06 15:03:57

标签: java junit static inner-classes

我需要有不同的参数集,所以我决定使用@Enclosed。但是,嵌套类必须是静态的,因此方法调用的所有现有方法/常量都必须是静态的。 但这很难,因为我无法改变所有这些方法的定义。

有没有办法使用@Enclosed而不使用static添加现有方法的定义?

这是一个例子,让你知道我在问什么。在这个例子中,由于data()是静态的,someTest类必须是静态的,所以如果我调用nonStaticMethod(),我得到了#34;不能对非静态方法进行静态引用..."在调用nonStaticMethod()的行。 但我不想将nonStaticMethod()重新定义为静态。

@RunWith(Enclosed.class)
public class EnclosedParameterizedTest extends EnclosedBase{

    @RunWith(Parameterized.class)
    public static class SomeTest {

        @Parameters
        public static Collection<Object[]> data() {
            return Arrays.asList(new Object[][]{
                    new Object[]{"NY"},
                    new Object[]{"CA"},
            });
        }

        String state;

        public SomeTest(String state) {
            this.state = state;
        }

        @Test
        public void verifyStateTest(){
            nonStaticMethod(); //a method already defined in parent of     
            //EnclosedBase which I cannot re-define
        }
    }
}

2 个答案:

答案 0 :(得分:4)

很多人都对此感到困惑。 “静态嵌套类”的意思是内部类没有对外部类的引用。不要求方法或字段是静态的。

例如,查找java.util.HashMap的源代码,有一个名为Entry的静态内部类,它实现了java.util.Map.Entry

static class Entry<K,V> implements Map.Entry<K,V> {
    final K key;
    V value;
    Entry<K,V> next;
    int hash;

    /**
     * Creates new entry.
     */
    Entry(int h, K k, V v, Entry<K,V> n) {
        value = v;
        next = n;
        key = k;
        hash = h;
    }

    public final K getKey() {
        return key;
    }

    public final V getValue() {
        return value;
    }
    // ... 

显然地图必须有多个条目,因此static关键字不会用于表示这是某种单身。

答案 1 :(得分:1)

不幸的是,Enclosed运行器要求封闭的类是静态的(又称&#34;嵌套类&#34;)。

编辑:实际上,JUnit永远不会实例化使用@RunWith(Enclosed.class)注释的类。除非基类具有使用JUnit注释(Enclosed@ClassRule等注释的字段或方法),否则使用@BeforeClass扩展另一个类的测试不会做任何事情。

我建议您通过委派而不是继承来共享代码。在您的情况下,您可以将nonStaticMethod()移至其他类:

@RunWith(Enclosed.class)
public class EnclosedParameterizedTest {

    @RunWith(Parameterized.class)
    public static class SomeTest {
        public final Helper helper = new Helper();

        @Parameters
        public static Collection<Object[]> data() {
            return Arrays.asList(new Object[][] {
                    new Object[] { "NY" },
                    new Object[] { "CA" },
            });
        }

        String state;

        public SomeTest(String state) {
            this.state = state;
        }

        @Test
        public void verifyStateTest(){
            helper.nonStaticMethod();
        }
    }
}

通常,委派比继承更灵活。 Java中继承的一个常见问题是类只能有一个基类。但另一个问题是嵌套类无法访问外部类的状态,因此不能共享除静态方法之外的代码。

编辑:如果这不是一个选项,您的嵌套类可以扩展您的基类:

@RunWith(Enclosed.class)
public class EnclosedParameterizedTest {

    @RunWith(Parameterized.class)
    public static class SomeTest extends EnclosedBase {

        @Parameters
        public static Collection<Object[]> data() {
            return Arrays.asList(new Object[][] {
                    new Object[] { "NY" },
                    new Object[] { "CA" },
            });
        }

        String state;

        public SomeTest(String state) {
            this.state = state;
        }

        @Test
        public void verifyStateTest(){
            nonStaticMethod();
        }
    }
}

或者,如果您需要针对不同测试的不同参数集,请考虑使用JUnitParams跑步者

@RunWith(JUnitParamsRunner.class)
public class MyParameterizedTest extends EnclosedBase {

    @Parameters({"NY", 
                 "CA" })
    @Test
    public void verifyStateTest(String state) {
        nonStaticMethod();
    }
}