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
Static initializer block or
Static method with #BeforeClass
What are the advantages of using one over another?
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!
Here's a couple of considerations that could be taken into account when deciding whether to use the static initialization block or #BeforeClass:
#BeforeClass is the antagonist of #AfterClass. So if you do initializations that require cleaning up later (like opening external resources) it would be better (from a semantic point of view) to use the annotated methods.
If you do complex initializations that might throw checked exceptions it's much more comfortable to use #BeforeClass, because you don't have to catch and wrap it into an unchecked exception.
If you want to use constant semantics (private static final String VARIABLE) with complex initialization, you will have no choice but to use the static initialization block or a static method.
There is a related post on SO: unit testing - What's the difference between using #BeforeClass and using instance or static variable in JUnit 4 Java?
If it's both static and final then you only have one choice: static initializer.
The compiler will prevent you from writing to a final field from inside a method, static or not.
EDIT: OK, you've removed the word 'final' from your question. In that case, it makes little difference. The static initializer will run once; so will the #BeforeClass method. Just pick whichever one you think is more readable.
It's not exactly the same behavior. #BeforeClass runs everytime the tests are run, a static initializer only once when the class is loaded. If your testrunner uses the same classloader, then in the case of #BeforeClass, you would re-run the initialization of the static variable. It depends on what you want to achieve here.
Related
Using JUnit all my runner classes implement a method that is annotated with
#BeforeClass
public static void setUp() throws Exception {}
There is a lot of mutual code.
I want to create a base runner that will hold all the base code and will allow sub classes to add more features.
This is all static. What is the best practice?
You should reconsider your design. The #BeforeClass annotation is intended to specify code that has to run exactly once for all tests. If you repeat the same code in multiple static methods annotated with #BeforeClass, in other words, execute the same action multiple times, it suggests that it is not the #BeforeClass semantic that you want.
Maybe you just want instance methods annotated with #Before
Otherwise, if it’s really about single time actions, just put a static method with the #BeforeClass annotation into the base class, and you’re done. The initialization of the subclass implies the initialization of the base class. The initialization of the base class will happen exactly once for all subclasses but that is what #BeforeClass is all about. As said, if you want an initialization once per subclass or once per test, it’s more likely that #Before is the feature you want.
Note further, that you can have code in static methods in a base class which is only executed when subclasses invoke it. Just place the code into a method without the #BeforeClass annotation. Then, methods in subclasses, having the annotation or not, may invoke the method of the base class. There is no need for an override relationship here.
As said; there is no "overriding" for static; and of course: static is by itself ... very often an indication for "design improvement required". Everybody who is writing serious unit tests knows that static things can make unit testing a night-mare. So we avoid static in our production code. But then, in our testing code, we just use it?!
And going one step further: some people claim that inheritance is not a good answer to "i have a lot of common code within my unit tests".
See here for example.
You could move the common code to a rule and reuse that rule in every test: https://github.com/junit-team/junit/wiki/Rules
This may be a simple question, but I could not find an answer with reasonable search.
I am trying to make a static method return a value more than once in multiple tests. I fail to achieve this with the mocked static method with PowerMock. To put this simply I have a JUnit test #BeforeClass like this
#RunWith(PowerMockRunner.class)
#PrepareForTest(StaticStuff.class)
public class MyTest extends TestCase {
#BeforeClass
public static void init() {
// Mock some stuff
PowerMockito.mockStatic(StaticStuff.class);
Mockito.when(StaticStuff.get()).thenReturn("something");
}
}
Now, this works for the first test accessing the static method, but the rest will receive 'null' (update: or any other value that the "real" method would return). I can fix the problem simply changing the #BeforeClass to #Before, thus making the static mock be recreated for every test. But afaik, this is not the correct way to do this. For this particular case this will do, but I believe there should be a way to provide information that the method may be called "any times".
Actually I understood from the documentation that the same value should be returned "infinite times by default" (but it doesn't. From Mockito documentation: 'Once stubbed, mocked method will always return stubbed value regardless of how many times it is called.'). Also I would expect that stating the amount of calls should be something this simple (but it isn't):
Mockito.when(StaticStuff.get()).thenReturn("something").times(10);
Maybe I am just missing something?
The tests should be independent from each other. If you use JUnit, the order of the tests is not determined at all (see https://github.com/junit-team/junit/wiki/Test-execution-order). I think creating mocks in #BeforeClass is actually a bad practice, since it can cause that the tests are depending on each other. So I would simply recommend to use #Before method to initialize all mocks, and use #BeforeClass only, if you prepare something really common for the tests (like a connection pool or something like that).
I have a unit test class which when ran individually passes. When I run it with all the other tests within the package it fails with the failure being that an independent static class has not been initialized. This independent static class is used by other classes and so it seems that its state is maintained between tests.
Is my observation correct or is something else happening? Also it would be good if someone could provide a link or something as reference.
Thanks!
This independent static class is used by other classes and so it seems that its state is maintained between tests.
Yes. That is what will happen. And this is just one of the reasons that statics are awkward.
Static fields exist for the lifetime of the classes that define them, and that generally means for the lifetime of the JVM. I tried to find a place in the JLS where this is stated explicitly. The closest I could find was JLS 8.3.1.1 which says:
"If a field is declared static, there exists exactly one incarnation of the field, no matter how many instances (possibly zero) of the class may eventually be created. A static field, sometimes called a class variable, is incarnated when the class is initialized (§12.4)."
Elsewhere the JLS says that a class is initialized only once.
The exception is when a class gets unloaded, but that won't happen here. Or at least, not with normal / default JUnit framework behaviour. (But it can be done: see Using different classloaders for different JUnit tests?)
And in case you are worried, there isn't any JUnit "magic" to reset the statics to their initial state (however you defines that). It is too complicated (and horrible) to contemplate implementing that.
Methods have no state (except while a given method is running, of course), so none is saved between invocations — even for static methods..
Any static field saves its state for the duration of the JVM's execution (unless code changes its value, of course). JUnit uses one JVM for all of its tests, so, yes, static fields save state between tests.
That's one of the biggest reason that people recommend not using static fields where it's possible to avoid them: it reduces the amount of global state you have to worry about, and thus makes it much easier to reason about tests.
Why the #BeforeClass method in JUnit is static whereas in TestNG its non-static? TestNG was developed as an improvement over JUnit, so why did they choose this way of implementation?
Since #BeforeClass runs only once, so making it static makes more sense than making it non static. Also in TestNG, on which instance the #BeforeClass method is called? Can someone cite an example for better understanding?
The main difference between JUnit and TestNG is the test class instantiation. JUnit always creates a new instance of the test class for each test method run. TestNG only creates one test class instance and then runs all test methods of this instance.
The JUnit approach guarantees the independency of all test methods. It just does not matter, in which order they run. Additionally, all instance fields are always setup the same for each test method. Initializing data, that is common for all test methods, must take place at the class level, thus it must be static. This is the reason, why the #BeforeClass method must be static.
The TestNG approch does not guarante the independency. In fact, you cannot use an instance field in the same manner as in JUnit tests. If you change such a field in one test method, the changed value is still observabl in another test method. However, this behavior has also an advantage: Sometimes there are dependencies between some test methods. With TestNG, a tester can express them.
Because of the one-instance-approach of TestNG, the #BeforeClass setup can also be a non-static method, but it is still run only once. It was a design decision, but testers using TestNG must be aware of that.
Making a method static or non-static has nothing to do with being able to invoke that method only once at the beginning. You can call a static method as many times as you want. You can call a non-static method exactly one. There is no necessary correlation between the two : being static and invoking once. At least, I am not aware of any direct consequence of making a method static which enables it to be invoked exactly once. static is rightly associated with single class, but not with single invocation.
Making a method static prevents it from accessing non-static members of the class. But with having a non-static #BeforeClass method, you can also access non-static members, there by giving you more scope to access class variables. Perhaps this is the reason why testng removed the restriction of #BeforeClass method being static.
I'm new to unit test. About the purpose of using #Before annotation in JUnit 4. I just don't know the point of using it:
public class FoodTestCase {
static private Food sandwich;
#BeforeClass
public static void initialise(){
sandwich = new Sandwich();
}
}
vs
public class FoodTestCase {
static private Food sandwich = new Sandwich();
}
What's the difference?
In this case it may not be necessary, as the initialization is really simple.
In case you have some logging, complex initialization or need to free some resources, you have to use #BeforeClass and #AfterClass
I think the idea is like that:
You use #AfterClass to free resources. Then it is logical to have #BeforeClass to acquire them. Because it may not be a good idea to let developer to guess that he need to use static block.
Almost no difference. But if constructor of Sandwich throws exception you cannot initialize it directly static private Food sandwich = new Sandwich(); but have to wrap initialization with try/catch block. However method initialise() may be declared as throws MyException, so the test case will fail if exception indeed thrown during initialization.
Suppose, you had all of your Food related data (say a Menu) setup at the backend in a database table. Your Food test cases could then pertain to updating the Menu (all the CRUD ops basically).
Instead of opening a DB connection for every test case (using #Before); it would be wise if you do it just once before you run all your test cases via a method marked #BeforeClass.
Now the use of a method makes sense as the setup would most probably be slightly complex (you may decide to use a Spring container to get your Connection from a DataSource) and you would not be able to achieve it with a single line where you declare your Connection object.
Similarly, you would use the #AfterClass to tear down your global setup (for all the test cases) i.e. closing your database connection here.
In your particular example - not much. However there is also #Before annotation which will run prior to every test in your class. Take a look at http://selftechy.com/2011/05/17/junit4-before-vs-beforeclass-after-vs-afterclass, it is explained well there.
#BeforeClass is for static initializations.
Instances created here will be reused across all of your #Test s
Whereas #Before is per #Test .
Usually #BeforeClass is reserved for objects which are relatively expensive to instantiate.
e.g. Database connections
Inheritance adds another wrinkle:
Let's say you have two JUnit tests that extend a common base class.
And let's say the base class has both a static initializer block and a #BeforeClass method.
In this case, the static initializer block will run once, while the #BeforeClass method will run twice.
So, if you have a very expensive computation or resource that you need set up across a whole suite of test cases that share a common base class, then you could use the static initializer block for that.