问题
JUnit's @BeforeClass
annotation must be declared static if you want it to run once before all the @Test
methods. However, this cannot be used with dependency injection.
I want to clean up a database that I @Autowire
with Spring Boot, once before I run my JUnit tests. I cannot @Autowire
static fields so I need to think of a work around. Any ideas?
回答1:
Just use @Before
(instead of @BeforeClass
) (or BeforeTransaction
(depending on how you initialize the database)). This annotation must been attached to an nonstatic public method.
Of course: @Before
run before EACH test case method (not like @BeforeClass
that runs only once.) But if you want to run it exactly once, then use an static marker field.
private static boolean initialized = false;
...
@Before
public void initializeDB() {
if (!initialized) {
... //your db initialization
initialized = true;
}
}
---
回答2:
Have a look at the DBUnit library - it's designed to perform the actions you're describing. It can create & tear down database instances and provides you with simple ways to do this.
回答3:
For JUnit5
: Test Execution Order and @TestInstance(Lifecycle.PER_CLASS)
Kotlin example:
@ExtendWith(SpringExtension::class)
@TestInstance(PER_CLASS)
class BeforeInstanceTests {
private var initialized: String = ""
private val callList: MutableList<String> = ArrayList()
@BeforeAll
fun beforeAllNonStatic() {
initialized = "initialized"
assertEquals(0, callList.size)
}
@Test
fun test1() {
assertEquals("initialized", initialized)
callList.add("test1")
}
@Test
fun test2() {
assertEquals("initialized", initialized)
callList.add("test2")
}
@Test
fun test3() {
assertEquals("initialized", initialized)
callList.add("test3")
}
@AfterAll
fun afterAllNonStatic() {
assertEquals("initialized", initialized)
assertEquals(3, callList.size)
assertTrue(callList.contains("test1"))
assertTrue(callList.contains("test2"))
assertTrue(callList.contains("test3"))
callList.clear()
initialized = ""
}
}
回答4:
Try this solution: https://stackoverflow.com/a/46274919/907576 :
with @BeforeAllMethods
/@AfterAllMethods
annotations you could execute any method in Test class in an instance context, where all injected values are available.
回答5:
Though accepted answer is clever, seems hacky. Have you tried using a normal Constructor?
public class MyJUnitTest {
public MyJUnitTest() {
// code for initializeDB
}
// Tests
}
来源:https://stackoverflow.com/questions/32952884/junit-beforeclass-non-static-work-around-for-spring-boot-application