【问题标题】:Why doesn't @DirtiesContext work in Spring Boot JUnit5(Jupiter) ? (OOM)为什么 @DirtiesContext 在 Spring Boot JUnit5(Jupiter) 中不起作用? (OOM)
【发布时间】:2022-02-01 19:56:20
【问题描述】:

我有几个以这种方式集成:

@SpringBootTest
@ExtendWith(SpringExtension.class)
@AutoConfigureMockMvc
@ActiveProfiles({"test", "test-batch"})
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
class HierarchyIntegrationTest {

@Test
@DirtiesContext
void hierarchy_test_a() {
//test code here.
}

@Test
@DirtiesContext
void hierarchy_test_b() {
//test code here.
}

@Test
@DirtiesContext
void hierarchy_test_c() {
//test code here.
}


}

@SpringBootTest
@ExtendWith(SpringExtension.class)
@AutoConfigureMockMvc
@ActiveProfiles("test")
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
class TicketPriceIntegrationTest {

    @Test
    @DirtiesContext
    void ticket_test_a() {
    //test code here.
    }

    @Test
    @DirtiesContext
    void ticket_test_b() {
    //test code here.
    }

    @Test
    @DirtiesContext
    void ticket_test_c() {
    //test code here.
    }

}

现在我如何验证@DirtiesContext 不起作用?

因为我所有的集成测试都使用Hikari连接数据库:

在每次新的集成中,我都会看到 Hikari 连接池的数量在增加,如下所示:

00:47:02.450 [INFO ] c.z.h.HikariDataSource - HikariPool-20 - Shutdown initiated...
00:47:03.061 [INFO ] c.z.h.HikariDataSource - HikariPool-20 - Shutdown completed.

00:47:02.450 [INFO ] c.z.h.HikariDataSource - HikariPool-21 - Shutdown initiated...
00:47:03.061 [INFO ] c.z.h.HikariDataSource - HikariPool-21 - Shutdown completed.

00:47:02.450 [INFO ] c.z.h.HikariDataSource - HikariPool-22 - Shutdown initiated...
00:47:03.061 [INFO ] c.z.h.HikariDataSource - HikariPool-22 - Shutdown completed.

每个新测试都应该相互排斥。

@DirtiesContext 应该已经处理好了,但是之前的 bean 似乎没有被丢弃。

因此我最终会出现内存泄漏。

 00:50:36.597 [ERROR] o.s.t.c.TestContextManager - Caught exception while allowing TestExecutionListener [org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener@550625bf] to prepare test instance [com.item.integration.IntegrationTest@5b59e4c6]
    java.lang.OutOfMemoryError: Java heap space

我正在使用:

Spring Boot 2.5.4
JUnit5 (Jupiter)

我该如何解决这个问题?

谢谢

【问题讨论】:

    标签: spring-boot junit spring-boot-test applicationcontext junit-jupiter


    【解决方案1】:

    Hikari poolName 通过 JVM 系统属性递增,这就是为什么您可以在每次 ApplicationContext 销毁后看到它的原因。这种破坏有效地重新创建了 Context 的所有 bean。

    来自 HikariConfig.class:

                synchronized(System.getProperties()) {
                    String next = String.valueOf(Integer.getInteger("com.zaxxer.hikari.pool_number", 0) + 1);
                    System.setProperty("com.zaxxer.hikari.pool_number", next);
                    return "HikariPool-" + next;
                }
    

    内存问题是别的,可以尝试增加JVM的堆大小..

    【讨论】:

    • 如何获得堆转储?使用-XX:+HeapDumpOnOutOfMemoryError 不会生成任何堆转储文件
    • 你到底是什么意思:This destruction effectively recreates ALL the beans of your Context.
    • 我的问题是如果创建了 HikariPool-27,那么是否创建了 26 个池并保存在应用程序上下文中?我的应用程序中没有那么多池,我只有 2 个。
    • 我的意思是你不必担心,你的上下文的bean的破坏,它们被正确地破坏和重新创建。不,在您的情况下,连接池被破坏了,但是如果您有其他 SpringTest 类配置了自定义上下文(例如:@MockBean、自定义配置文件..),Spring 将尝试缓存上下文以供以后重用。在这种情况下,您可以有许多连接池处于活动状态(这可能是您的问题,但我不能告诉docs.spring.io/spring-framework/docs/current/reference/html/…
    • 嘿,我可以告诉 Spring 不要缓存应用程序上下文吗?
    猜你喜欢
    • 2023-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-23
    • 1970-01-01
    • 2021-07-07
    • 2019-07-03
    相关资源
    最近更新 更多