Search code examples
javajunit4

Running JUnitCore with instances instead of classes


I'm looking to run JUnit 4.12+ programmatically, and a cursory search for doing so yielded (amongst many other similar posts) this answer, which prescribes the following basic solution:

@RunWith(Suite)
@Suite.SuiteClasses ({
    MyTestClass1.class,
    MyTestClass2.class
})
public class MyTestSuite {
}

Result testResults = JUnitCore.runClasses(MyTestSuite.class);

...and I was able to get this working, no sweat. So far so good!

Problem is: I have some pretty sophisticated test classes that need to be instantiated/injected with very specific properties at runtime...not something that can be done from inside a no-arg constructor. But the above method (specifying to just run any old instance of a set of classes) doesn't allow you to instantiate your test classes, configure them, and then run them.

Is there a way to do this? I couldn't find anything looking at the JUnit API. I am looking for something like:

MyTestClass1 mtc1 = new MyTestClass1(...);
MyTestClass2 mtc2 = new MyTestClass2(...);
Result testResults = JUnitCore.run(mtc1, mtc2);

Solution

  • I got this working with a custom Runner with sample (Groovy pseudo-code) as follows:

    class MyRunner extends Runner {
        @Override
        Description getDescription() {
            return null
        }
    
        @Override
        void run(RunNotifier notifier) {
            // LoginTests.class is a test class I want to run
            LoginTests loginTests = new LoginTests(<my args here>)
    
            Description description = Description.createSuiteDescription(LoginTests)
            notifier.fireTestStarted(description)
            try {
                log.info("About to doSomething()...")
                loginTests.doSomething()
                log.info("Did it...")
                notifier.fireTestFinished(description)
            } catch(Throwable throwable) {
                log.info("doSomething() failed...")
                notifier.fireTestAssumptionFailed(new Failure(description, throwable))
            }
        }
    }
    
    Result testResults = new JUnitCore().run(Request.runner(new MyRunner()))