JUnit RunListener is removed on fail()

2019-06-14 13:14发布

问题:

I am using a RunListener to let test fail when they write to System.out, but when I fail() a unittest, the listener is removed. Is there any way to let tests fail without removing the Listener?

For clarification a code example

public class OutputListenerTest {
  @Test
  public void testPrintIsDicovered() {
    JUnitCore runner = new JUnitCore();
    // the OutputListener calls fail() when something was written
    runner.addListener(new OutputListener());
    Result result = runner.run(TestWithOutput.class);
  }

  public static class TestWithOutput {
    @Test
    public void testOutput1() {
      System.out.println("foo");
    }

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

What I'd expect: 2 failed tests
What is: The first test fails and the Listener is removed.

As requested, here is the OutputListener code http://paste.robbi5.com/4916ca5b Is it ok to not paste it here, it's pretty long and won't help solving the question?

a little more context
I picked the RunListener, because it works pretty easy with maven, just add

  <properties>
    <property>
      <name>listener</name>
      <value>OutputListener</value>
    </property>
  </properties> 

to the maven-surefire-plugin and mvn test shows what tests use System.out in some way.

回答1:

Add a Runner to add the listener.

public class AddListenerRunner extends BlockJUnit4ClassRunner {

    public AddListenerRunner(Class<?> klass) throws InitializationError {
        super(klass);
    }

    @Override public void run(RunNotifier notifier){
        notifier.addListener(new OutputListener());
        super.run(notifier);
    }
}

You can then use that in your tests like this.

@RunWith(AddListenerRunner.class)
public class OutputListenerTest {
    @Test
    public void testOutput1() {
      System.out.println("foo");
    }

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