为什么jUnit的fixtureSetup必须是静态的? [英] Why must jUnit's fixtureSetup be static?

查看:102
本文介绍了为什么jUnit的fixtureSetup必须是静态的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我用jUnit的@BeforeClass注释标记了一个方法,并得到了这个例外,说它必须是静态的。理由是什么?这就迫使我的所有init都在静态字段上,据我所知,没有任何理由。

I marked a method with jUnit's @BeforeClass annotation, and got this exception saying it must be static. What's the rationale? This forces all my init to be on static fields, for no good reason as far as I see.

在.Net(NUnit)中,情况并非如此。

In .Net (NUnit), this is not the case.

编辑 - 使用@BeforeClass注释的方法只运行一次这与静态方法无关 - 可以有一个非静态方法只运行一次(如在NUnit中)。

Edit - the fact that a method annotated with @BeforeClass runs only once has nothing to do with it being a static method - one can have a non-static method run only once (as in NUnit).

推荐答案

JUnit 总是创建一个实例每个@Test方法的测试类。 这是一项基本的设计决策,可以更轻松地编写没有副作用的测试。好的测试没有任何运行顺序依赖性(参见 FIRST )和为每个测试创建测试类的新实例及其实例变量对于实现这一点至关重要。一些测试框架为所有测试重用相同的测试类实例,这导致在测试之间意外创建副作用的更多可能性。

JUnit always creates one instance of the test class for each @Test method. This is a fundamental design decision to make it easier to write tests without side-effects. Good tests do not have any order-of-run dependencies (see F.I.R.S.T) and creating fresh instances of the test class and its instance variables for each test is crucial in achieving this. Some testing frameworks reuse the same test class instance for all tests, which leads to more possibilities of accidentally creating side-effects between tests.

并且因为每种测试方法都有自己的测试方法例如,@ BeforeClass / @ AfterClass方法是实例方法是没有意义的。否则,应该在哪个测试类实例上调用这些方法?如果@ BeforeClass / @ AfterClass方法可以引用实例变量,那么只有一个@Test方法可以访问那些相同的实例变量 - 其余的将具有实例变量at它们的默认值 - 以及@Test方法将被随机选择,因为.class文件中的方法顺序是未指定的/编译器相关的(IIRC,Java的反射API以与它们中声明的相同的顺序返回方法。类文件,虽然也没有指定该行为 - 我已经写了,用于按行号对它们进行实际排序)。

And because each test method has its own instance, it makes no sense for the @BeforeClass/@AfterClass methods to be instance methods. Otherwise, on which of the test class instances should the methods be called? If it would be possible for the @BeforeClass/@AfterClass methods to reference instance variables, then only one of the @Test methods would have access to those same instance variables - the rest would have the instance variables at their default values - and the @Test method would be randomly selected, because the order of methods in the .class file is unspecified/compiler-dependent (IIRC, Java's reflection API returns the methods in the same order as they are declared in the .class file, although also that behaviour is unspecified - I have written a library for actually sorting them by their line numbers).

因此,强制执行这些方法是唯一合理的解决方案。

So enforcing those methods to be static is the only reasonable solution.

这是一个例子:

public class ExampleTest {

    @BeforeClass
    public static void beforeClass() {
        System.out.println("beforeClass");
    }

    @AfterClass
    public static void afterClass() {
        System.out.println("afterClass");
    }

    @Before
    public void before() {
        System.out.println(this + "\tbefore");
    }

    @After
    public void after() {
        System.out.println(this + "\tafter");
    }

    @Test
    public void test1() {
        System.out.println(this + "\ttest1");
    }

    @Test
    public void test2() {
        System.out.println(this + "\ttest2");
    }

    @Test
    public void test3() {
        System.out.println(this + "\ttest3");
    }
}

打印:

beforeClass
ExampleTest@3358fd70    before
ExampleTest@3358fd70    test1
ExampleTest@3358fd70    after
ExampleTest@6293068a    before
ExampleTest@6293068a    test2
ExampleTest@6293068a    after
ExampleTest@22928095    before
ExampleTest@22928095    test3
ExampleTest@22928095    after
afterClass

如您所见,每个测试都使用自己的实例执行。 JUnit的作用与此基本相同:

As you can see, each of the tests is executed with its own instance. What JUnit does is basically the same as this:

ExampleTest.beforeClass();

ExampleTest t1 = new ExampleTest();
t1.before();
t1.test1();
t1.after();

ExampleTest t2 = new ExampleTest();
t2.before();
t2.test2();
t2.after();

ExampleTest t3 = new ExampleTest();
t3.before();
t3.test3();
t3.after();

ExampleTest.afterClass();

这篇关于为什么jUnit的fixtureSetup必须是静态的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆