JUnit @BeforeClass非静态解决Spring Boot应用程序

时间:2015-10-05 16:01:22

标签: spring unit-testing junit dependency-injection spring-boot

如果希望JUnit的@BeforeClass注释在所有@Test方法之前运行一次,则必须将其声明为静态。但是,这不能用于依赖注入。

在运行JUnit测试之前,我想用Spring Boot清理一个@Autowire的数据库。我不能@Autowire静态字段所以我需要考虑一个解决方法。有什么想法吗?

6 个答案:

答案 0 :(得分:26)

只需使用@BeforeClass(而不是BeforeTransaction)(或@Before(取决于您初始化数据库的方式))。此注释必须附加到非静态公共方法。

当然:@BeforeClass在每个测试用例方法之前运行(不像只运行一次的private static boolean initialized = false; ... @Before public void initializeDB() { if (!initialized) { ... //your db initialization initialized = true; } } --- 。)但是如果你只想运行一次,那么使用静态标记字段。

{{1}}

答案 1 :(得分:1)

试试这个解决方案: https://stackoverflow.com/a/46274919/907576

使用@BeforeAllMethods / @AfterAllMethods注释,您可以在实例上下文中的Test类中执行任何方法,其中所有注入的值都可用。

答案 2 :(得分:1)

对于 JUnit5 Test Execution Order@TestInstance(Lifecycle.PER_CLASS)

Kotlin示例:

@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 = ""
    }
}

答案 3 :(得分:0)

查看DBUnit库 - 它旨在执行您正在描述的操作。它可以创造&amp;拆除数据库实例并为您提供简单的方法来执行此操作。

答案 4 :(得分:0)

尽管公认的答案很聪明,但似乎很客气。您是否尝试过使用普通的构造函数?

public class MyJUnitTest {

    public MyJUnitTest() {
       // code for initializeDB
    }

    // Tests

}

答案 5 :(得分:0)

对此问题有几种解决方案:

1-如@Ralph所述,您可以使用Junit的@Before或@BeforeEach批注,并使用布尔变量作为标志。 但是,此解决方案似乎是一种解决方法!因为您滥用它,在某些情况下会造成混淆。

2-您可以改为使用TestNG,并且不再需要使用静态方法,从而可以使用Spring的注入对象。 不过,这种解决方案似乎很麻烦!从您当前的测试框架切换到TestNG需要花费时间和工作。

3-第三种解决方案是使用构造函数。 但是,这种解决方案对于继承中的注入将很麻烦。

4-最后,我建议使用针对此类情况构建的@PostConstruct。 请参阅下面的简单示例代码:

@PostConstruct
public void init(){
    initDatabase();
}