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!
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.
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With