JUnit @BeforeClass non-static work around for Spring Boot application

落花浮王杯 提交于 2020-01-01 04:01:22

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!