1

I made my own JUnit-Runner by implementing org.junit.runner.Runner, so that I can run my UnitTests with them using the @RunWith-Annotation.

It lookes somewhat like this:

public class MyRunner extends Runner {

    private Context myContext;
    myContext.init();
    private final BlockJUnit4ClassRunner runner;

    public MyRunner(final Class<?> clazz) throws InitializationError {
        myContext = new Context();

        runner = new BlockJUnit4ClassRunner(clazz);
    }

    @Override
    public void run(final RunNotifier notifier) {
        runner.run(notifier);
    }

    @Override
    public Description getDescription() {
        return runner.getDescription();
    }

    public void filter(final Filter filter) throws NoTestsRemainException {
        runner.filter(filter);
    }
}

To clean up resources, I have to shut down MyContext by calling MyContext.close(). Where should I invoke this so that my resources are cleand up after the tests have run?

Bob
  • 5,510
  • 9
  • 48
  • 80

2 Answers2

1

I'm not sure what you're trying to achive but have you already had a look at JUnit's Rules?

public class MyContextRule extends ExternalResource {

    private final Context myContext;

    public MyContextRule()  {
        myContext = new Context();
    }

    @Override
    protected void before() throws Throwable {
        myContext.init();
    }

    @Override
    protected void after() {
        myContext.close();
    }

}

Usage:

public class MyTest {
    @ClassRule
    public static MyContextRule contextRule = new MyContextRule(); 

    //...
}

JUnit Rules advantage over Runners is that you can have multiple of them, while you only can have one runner.

So, your custom Rule could be used with any runner that may be introduced by a random testframework that you may come across in the future...

Markus Mitterauer
  • 1,560
  • 1
  • 14
  • 28
-1

Where should I invoke this so that my resources are cleand up after the tests have run ?

UPDATED MY ANSWER, you can use org.junit.runner.notification.RunListener as shown below:

(1) Create your own RunListener class:

public class MyRunnerListener extends RunListener {
    private Context context;

    public MyRunnerListener(Context context) {
        this.context = context;
    }

     void   testRunFinished(Result result)  {
          context.close();
     }
}

(2) Use the MyRunnerListener inside MyRunner :

public class MyRunner extends Runner {

    private Context myContext;
    MyRunnerListener runnerListener;
    private final BlockJUnit4ClassRunner runner;

    public MyRunner(final Class<?> clazz) throws InitializationError {
        myContext = new Context();
        myContext.init();
        runnerListener = new MyRunnerListener(myContext);

        runner = new BlockJUnit4ClassRunner(clazz);
    }

    @Override
    public void run(final RunNotifier notifier) {
        notifier.addListener(runnerListener);
        runner.run(notifier);
    }

    @Override
    public Description getDescription() {
        return runner.getDescription();
    }

    public void filter(final Filter filter) throws NoTestsRemainException {
        runner.filter(filter);
    }
}

P.S.: If you don't want to use the Runner, then you can follow the answer from Markus (which uses TestRule, NOT TestRunner).

Bob
  • 5,510
  • 9
  • 48
  • 80
Vasu
  • 21,832
  • 11
  • 51
  • 67
  • That doesn't answer the question as this applies to classes under test, but not the runner. – Bob Nov 18 '16 at 16:04
  • Updated the answer, look at it – Vasu Nov 18 '16 at 16:15
  • That won't work because a runner might be used by multiple test classes. – Bob Nov 18 '16 at 16:16
  • I have tested this and as there will be multiple testrunner objects (one for each Test Class) and each will close their context – Vasu Nov 18 '16 at 16:30
  • 1
    The solution also contradicts the idea of the Runner. The class under test shouldn't be required to modify the state of the runner. – Bob Nov 18 '16 at 16:31
  • I accept with this point, but your first point states that it does not work.. which is not correct ? do you agree ? – Vasu Nov 18 '16 at 16:34
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/128478/discussion-between-javaguy-and-bob). – Vasu Nov 18 '16 at 17:27
  • 1
    Using the RunListener makes sense. The code you posted doesn't work, though. I'll update it. – Bob Nov 19 '16 at 14:29