Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JUnit - Do static classes maintain state between test classes?

Tags:

java

junit

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!

like image 900
n00b Avatar asked Mar 27 '14 03:03

n00b


People also ask

Can static class have state?

Static means stated. Just know how static classes work in the CLR: You can't control the time when static constructors are called. Static classes have a separate state for each calling program.

Does JUnit creates a new instance for each test?

By default, JUnit creates a new instance of the test class before executing each test method. This helps us to run individual test methods in isolation and avoids unexpected side effects. Notice how the methods annotated with @BeforeAll and @AfterAll are static methods.

Do JUnit tests run concurrently?

Once parallel test execution property is enabled, the JUnit Jupiter engine will execute tests in parallel according to the provided configuration with declared synchronization mechanisms.

Is it necessary to write the test class to test every class?

No. It is a convention to start with one test class per class under test, but it is not necessary. Test classes only provide a way to organize tests, nothing more.


2 Answers

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.

like image 102
Stephen C Avatar answered Oct 14 '22 09:10

Stephen C


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.

like image 26
yshavit Avatar answered Oct 14 '22 10:10

yshavit