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
Could Not Serialize Object Cause of Hibernateproxy
How to Write Swap Method in Java
Why Integer.Max_Value + 1 == Integer.Min_Value
Java Import VS Code Performance
How Does the JPA @Sequencegenerator Annotation Work
Permutation Algorithm Without Recursion? Java
Attach the Source in Eclipse of a Jar
Xml Element with Attribute and Content Using Jaxb
Implementing Custom Methods of Spring Data Repository and Exposing Them Through Rest
In Which Thread Do Completablefuture's Completion Handlers Execute
How to Fix a Compilation Error for Unhandled Exception on Call to Thread.Sleep()
How to Call Methods in Constructor in Java
Cannot Instantiate the Type List<Product>