Junit - Run Set Up Method Once

Junit - run set up method once

Although I agree with @assylias that using @BeforeClass is a classic solution it is not always convenient. The method annotated with @BeforeClass must be static. It is very inconvenient for some tests that need instance of test case. For example Spring based tests that use @Autowired to work with services defined in spring context.

In this case I personally use regular setUp() method annotated with @Before annotation and manage my custom static(!) boolean flag:

private static boolean setUpIsDone = false;
.....
@Before
public void setUp() {
if (setUpIsDone) {
return;
}
// do the setup
setUpIsDone = true;
}

running setup method for junit only once

You can use the @Before method, you just need a bit of checking to do:

public class EntityRepositoryTest {

@Autowired
EntityJPARepository EntityRepo;

Entity entity;

@Before
public void setup() {
if (entity == null) { // true only for first pass
entity = //initializes entity with values
EntityRepo.save(entity);
}
}

//some tests on repo

}

Alternatively, you can add an @After method that deletes the entity.

Run JUnit setup and teardown exactly once for any test(s) run

I was able to accomplish what I needed using two separate methods. I'd prefer if just one method worked, but this will do...

I have a custom RunListener class that implements testRunFinished:

public class MyRunListener extends RunListener
{
@Override
public void testRunFinished(Result result) throws Exception
{
//Do whatever teardown needs to be done
}
}

I then have a custom BlockJUnit4ClassRunner class with the following run() method:

private static boolean listenerAdded = false;
@Override
public void run(RunNotifier notifier)
{
//listenerAdded required or else the listener will be added once for every test case, and testRunFinished will be run multiple times
if(!listenerAdded)
{
listenerAdded = true;
notifier.addListener(new MyRunListener());
}
super.run(notifier);
}

An abstract test case class uses the annotation:

@RunWith(MyRunner.class)

I was hoping that I could also implement testRunStarted in MyRunListener but it didn't work. Apparently adding the listener like this in MyRunner, the listener isn't added until after the testRunStarted method would have been run, so it isn't being executed. The workaround for this is, as mentioned in the original question, to use a static initilizer in AbstractTestCase:

@RunWith(MyRunner.class)
public class AbstractTestCase
{
private static boolean setupDone = false;
static
{
if(!setupDone)
{
setupDone = true;
//Do whatever setup needs to be done
}
}
...

If anyone knows of a way to add MyRunListener that will allow the use of testRunStarted that would be nice, but in the meantime this works.

How JUnit manages running @BeforeClass only once which is defined inside the test class

Methods annotated with @BeforeClass must be static. JUnit doesn't need any instance of the test class to call it.



Related Topics



Leave a reply



Submit