Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

@BeforeClass vs static{}

Tags:

I am writing some test cases using JUnit. I need to initialize some static variables which will be used for all the test cases in that class.

For this I can use either

  1. Static initializer block or
  2. Static method with @BeforeClass

What are the advantages of using one over another?

like image 460
shantanu Avatar asked Mar 19 '13 06:03

shantanu


People also ask

What is the difference between @before and @BeforeClass annotation?

The code marked @Before is executed before each test, while @BeforeClass runs once before the entire test fixture.

What is the difference between @BeforeClass and @before?

@BeforeTest method executes only once before the first @Test method. @BeforeClass executes before each class. If there are separate @BeforeTest and @BeforeClass methods in different classes, then all the @BeforeTest methods will execute first but @BeforeClass methods will be executing as per the respective classes.

What is @BeforeClass in Junit?

org.junitAnnotating a public static void no-arg method with @BeforeClass causes it to be run once before any of the test methods in the class. The @BeforeClass methods of superclasses will be run before those of the current class, unless they are shadowed in the current class.

How do you initialize a static variable in Junit?

You could call the main method of classA . i.e. ClassA. main(somestrArray) and it should do the initialization. But if you don't want to do that then you could create your junit test in the same package as the original class and you would be able to access the protected variables .


1 Answers

There are very different semantics for @BeforeClass or a static initializer.

A static initializer is invoked by the JVM and not by JUnit. If an exception is thrown within a static initializer, the test framework might not be able to catch and report the exception. Furthermore, the invocation time of the static initializer is not well-defined compared to the @BeforeClass method. It will be run only once per class loader on its first actual use which is for example the access of a static property, a static method or one of its constructors. Sometimes, it might be hard to figure out when this will be. (If you do not use inheritence: You might one day or some coworker will refactor your test case. If not today, the choice for a static initializer might introduce nasty bugs in the future.)

On the other hand, @BeforeClass is run before each class's tests are run. If a class would be subject to different tests, for example due to tests built on inheritance, the static initializer will only run for the first test using this class. This means that you made your test order dependent what is something you never want.

Note that the semantic difference between the two options is bigger than between using @Before or a constructor for a test. As a final argument, think about the documentary value of the annotations. It makes your intentions more readable.

The only exception for this rule would be immutable constants. Those should be initialized within their declaration in order to keep your code concise and in order to respect compile time constants. If your values are however mutable, you should not use static values at all. Again, mutable values that are altered in a test introduce an order dependency to your test which is to be avoided.

TL;DR: Use @BeforeClass!

like image 168
Rafael Winterhalter Avatar answered Oct 26 '22 13:10

Rafael Winterhalter