用于 Spring Boot 应用程序的 JUnit @BeforeClass 非静态工作

Posted

技术标签:

【中文标题】用于 Spring Boot 应用程序的 JUnit @BeforeClass 非静态工作【英文标题】:JUnit @BeforeClass non-static work around for Spring Boot application 【发布时间】:2016-01-02 08:41:56 【问题描述】:

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

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

【问题讨论】:

【参考方案1】:

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

【讨论】:

【参考方案2】:

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

当然:@Before 在每个测试用例方法之前运行(不像 @BeforeClass 只运行一次。)但是如果你想只运行一次,那么使用静态标记字段。

private static boolean initialized = false;
...
@Before
public void initializeDB()  
   if (!initialized) 
       ... //your db initialization
       initialized = true;
   

---

【讨论】:

这就是我必须使用 JUnit 时所做的。但是我更喜欢使用在非静态方法上具有所有可用注释的 TestNG:在您使用 TestNG 的情况下,@BeforeClass 将在非静态方法上定义,并且将在该类中的所有测试方法之前执行一次。 @AfterClass 有解决方法吗?我想删除数据库中插入的所有数据,因为我使用的是外部数据库。 @LunaticJape:我的工作方法是使用@After 方法将实例(@Autowired 字段值)传递给静态字段,然后在@AfterClass 方法中使用此字段。 @LunaticJape 见***.com/questions/37083647/…【参考方案3】:

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

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

【讨论】:

这不起作用,因为这些注释在 Spring Boot 应用程序中不存在。问题清楚地说是Spring Boot应用程序!不要给出行不通的建议。 在上述解决方案中,引用了带有注释的依赖项。因为 *** 不允许重复的答案,所以我只是提到了对另一个更具描述性的答案的引用。【参考方案4】:

虽然接受的答案很聪明,但似乎很老套。您是否尝试过使用普通的构造函数?

public class MyJUnitTest 

    public MyJUnitTest() 
       // code for initializeDB
    

    // Tests


【讨论】:

这行不通。 JUnit 为每个\@Test 创建一个新的测试类实例。所以使用构造函数实际上与 \@Before 相同,而不是 \@BeforeClass【参考方案5】:

对于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 = ""
    

【讨论】:

以上是关于用于 Spring Boot 应用程序的 JUnit @BeforeClass 非静态工作的主要内容,如果未能解决你的问题,请参考以下文章

跨域不适用于 Spring Boot

用于抑制 BatchDataInitializer 的 Spring-Boot 配置

Spring-Boot 不适用于 Flyway

cors 不适用于我的 Spring Boot 应用程序

Spring Web-mvc 不适用于 Spring Boot [Spring cloud]

Spring Boot 2 不适用于 Postgres