Issue
Currently the JUnit 5 API only allows @BeforeAll
on a method that is static.
So if I do something like this, it will not compile:
@BeforeAll
fun setup() {
MockitoAnnotations.initMocks(this)
mvc = MockMvcBuilders.standaloneSetup(controller).build()
}
In order to have a static method in Kotlin, I have to use companion object
like this:
companion object {
@JvmStatic
@BeforeAll
fun setup() {
MockitoAnnotations.initMocks(this)
mvc = MockMvcBuilders.standaloneSetup(smsController).build()
}
}
This will compile, but I don't have access to variables from the parent class. So what would be the idiomatic way to invoke JUnit 5 @BeforeAll
with Kotlin?
Solution
As stated in the documentation of @BeforeAll
:
Denotes that the annotated method should be executed before all @Test methods in the current class; analogous to JUnit 4’s @BeforeClass. Such methods must be static and are inherited.
The above is true for both Kotlin and Java. Keep in mind that by default Junit will create a separate instance of a test class per test case. It makes sense that @BeforeAll
will only work with static methods since it's supposed to be invoked before any code of current test case. A static method has no access to instance members because it can be invoked without an instance.
As stated in Spring documentation:
The "standaloneSetup" on the other hand is a little closer to a unit test.
The example shows that you should just use instance members like so:
class StandaloneTest {
val smsController = ... // create instance of controller
val MockMvcBuilders.standaloneSetup(smcController).build()
}
The usefulness of @BeforeAll
is limited and should generally be avoided as it potentially encourages runtime dependencies between test cases.
Answered By - miensol
Answer Checked By - David Goodson (JavaFixing Volunteer)