为什么多个JUnit TestWatchers不产生多个测试方法调用?

时间:2018-10-01 21:34:16

标签: java junit

我在测试套件中的每个测试上都使用了多个JUnit TestWatcher。我担心每个TestWatcher都在调用base.evaluate(),而每个测试实际上正在运行多次(每次调用base.evaluate()一次)。 很棒,这似乎没有发生,但是我对为什么会如此感到困惑。

为什么单个测试中没有多个JUnit TestWatcher导致对测试方法的多次调用?

我认为我对这些组件(尤其是base.evaluate())如何相互作用有一些根本性的误解,但还没有找到任何好的方法来解决我的困惑。

import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestWatcher;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;

public class SimpleTest {

    @Rule
    public TestWatcher testWatcher1 = new TestWatcher() {
        @Override
        public Statement apply(Statement base, Description description) {
            return new Statement() {
                public void evaluate() throws Throwable {
                    try {
                        System.out.println("testWatcher1");
                        base.evaluate();
                    } catch (Throwable e) {
                        e.printStackTrace();
                    }
                }
            };
        }
    };

    @Rule
    public TestWatcher testWatcher2 = new TestWatcher() {
        @Override
        public Statement apply(Statement base, Description description) {
            return new Statement() {
                public void evaluate() throws Throwable {
                    try {
                        System.out.println("testWatcher2");
                        base.evaluate();
                    } catch (Throwable e) {
                        e.printStackTrace();
                    }
                }
            };
        }
    };


    @Test
    public void test() {
        System.out.println("test");
    }
}

输出:

testWatcher2
testWatcher1
test

Process finished with exit code 0

待进一步调查: 在每个System.out.println(base.toString());调用中添加evaluate()会产生一些非常有趣的输出:

testWatcher2
com.glenpierce.Tests.base.SimpleTest$1$1@3c09711b
testWatcher1
org.junit.internal.runners.statements.InvokeMethod@5cc7c2a6
test

Process finished with exit code 0

似乎每个TestWatcher都在寻找不同的范围。我是无意中嵌套了这些东西吗?

1 个答案:

答案 0 :(得分:0)

JUnit中的规则经过设计,以便它们彼此链接。一个规则中的base.evaluate()会使下一个规则运行,直到所有规则都运行为止。仅当所有规则都调用base.evaluate()时,测试方法才会运行。