简体   繁体   中英

Why do multiple JUnit TestWatchers not spawn multiple test method calls?

I'm using multiple JUnit TestWatchers on each of the tests in my test suite. I was worried that each TestWatcher was calling base.evaluate() and each test was actually being run multiple times (once by each call to base.evaluate() ). That does not seem to be happening, which is great , but I'm confused as to why that is the case.

Why don't multiple JUnit TestWatchers in a single test result in multiple calls to the test method?

I think I have some fundamental misunderstanding of how these components (in particular base.evaluate() ) interact, but haven't found any good explanations that have resolved this confusion on my part.

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");
    }
}

Output:

testWatcher2
testWatcher1
test

Process finished with exit code 0

Upon further investigation: Adding System.out.println(base.toString()); inside of each of those evaluate() calls lead to some really interesting output:

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

Process finished with exit code 0

It seems like each TestWatcher is looking at a different scope. Am I unintentionally nesting these things?

Rules in JUnit are designed so that they are linked to each other. base.evaluate() in one rule causes the next rule to run, until all the rules have run. Only if all the rules calls base.evaluate() then the test method is run.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM