diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..965f6f6 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,40 @@ +name: CI + +on: + pull_request: + branches: [main, develop] + +concurrency: + group: ci-${{ github.event.pull_request.number }} + cancel-in-progress: true + +permissions: + contents: read + +jobs: + test: + runs-on: ubuntu-24.04 + timeout-minutes: 30 + steps: + - uses: actions/checkout@v4 + + - name: Set up JDK 21 + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: '21' + + - name: Set up Gradle + uses: gradle/actions/setup-gradle@v4 + + # 통합 테스트는 Testcontainers로 Postgres를 띄운다. GitHub 호스티드 러너에는 Docker가 기본 설치돼 있다. + - name: Test + run: ./gradlew test --console=plain + + - name: Upload test report + if: failure() + uses: actions/upload-artifact@v4 + with: + name: test-report + path: build/reports/tests/test + retention-days: 7 diff --git a/src/test/java/com/bcsdlab/bcsdinternalapiv2/BcsdInternalApiV2ApplicationTests.java b/src/test/java/com/bcsdlab/bcsdinternalapiv2/BcsdInternalApiV2ApplicationTests.java index 1d73966..447b65b 100644 --- a/src/test/java/com/bcsdlab/bcsdinternalapiv2/BcsdInternalApiV2ApplicationTests.java +++ b/src/test/java/com/bcsdlab/bcsdinternalapiv2/BcsdInternalApiV2ApplicationTests.java @@ -1,21 +1,8 @@ package com.bcsdlab.bcsdinternalapiv2; import org.junit.jupiter.api.Test; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.testcontainers.service.connection.ServiceConnection; -import org.springframework.test.context.TestPropertySource; -import org.testcontainers.containers.PostgreSQLContainer; -import org.testcontainers.junit.jupiter.Container; -import org.testcontainers.junit.jupiter.Testcontainers; -@Testcontainers -@SpringBootTest -@TestPropertySource(properties = "app.jwt.secret=test-only-secret-key-not-for-production-32bytes-min") -class BcsdInternalApiV2ApplicationTests { - - @Container - @ServiceConnection - static PostgreSQLContainer postgres = new PostgreSQLContainer<>("postgres:16-alpine"); +class BcsdInternalApiV2ApplicationTests extends IntegrationTestSupport { @Test void contextLoads() { diff --git a/src/test/java/com/bcsdlab/bcsdinternalapiv2/IntegrationTestSupport.java b/src/test/java/com/bcsdlab/bcsdinternalapiv2/IntegrationTestSupport.java index bfc2636..40ea7ff 100644 --- a/src/test/java/com/bcsdlab/bcsdinternalapiv2/IntegrationTestSupport.java +++ b/src/test/java/com/bcsdlab/bcsdinternalapiv2/IntegrationTestSupport.java @@ -1,9 +1,13 @@ package com.bcsdlab.bcsdinternalapiv2; +import java.util.List; +import java.util.Set; +import org.junit.jupiter.api.BeforeEach; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc; +import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.test.context.DynamicPropertyRegistry; import org.springframework.test.context.DynamicPropertySource; import org.springframework.test.web.servlet.MockMvc; @@ -13,19 +17,28 @@ * 통합 테스트 공통 베이스. Postgres 컨테이너를 테스트 클래스마다 새로 띄우지 않도록, * 정적 초기화 블록에서 JVM당 한 번만 기동하는 Testcontainers 공식 "싱글턴 컨테이너" 패턴을 쓴다. * - *

{@code @Testcontainers}/{@code @Container}를 쓰지 않는 이유: 그 조합은 컨테이너 생명주기를 - * 테스트 클래스 단위로 관리해서(클래스마다 기동), 클래스가 늘어날수록 기동 비용이 누적된다. - * 여기서는 정적 필드를 상속받는 모든 하위 클래스가 같은 컨테이너 인스턴스를 공유한다. + *

{@code @Testcontainers}/{@code @Container}를 쓰지 않는 이유: 그 조합은 컨테이너를 테스트 클래스가 + * 끝날 때 내리는데, Spring은 같은 설정의 컨텍스트를 다음 클래스에서 재사용하므로 두 번째 클래스부터 + * 이미 내려간 컨테이너에 연결하려다 실패한다. * - *

기존 7개 테스트 클래스(auth 4, member 2, 컨텍스트 로딩 1)는 각자 컨테이너를 띄우는 방식을 - * 그대로 쓴다 — 이 클래스로의 이전은 선택적 후속 작업이다(T-01). + *

모든 통합 테스트가 같은 DB를 쓰므로, 테스트마다 마이그레이션이 넣는 기준 데이터를 뺀 전 테이블을 + * 비운다. 각 테스트의 {@code @BeforeEach}는 이 메서드 다음에 실행된다. */ @SpringBootTest @AutoConfigureMockMvc public abstract class IntegrationTestSupport { + /** Flyway 이력과 마이그레이션이 시드하는 기준 데이터 테이블. */ + private static final Set PRESERVED_TABLES = + Set.of("flyway_schema_history", "track", "position", "dues_exemption_reason"); + + /** + * 설정(목 빈, 프로퍼티)이 다른 테스트 클래스마다 Spring 컨텍스트가 따로 캐시되고 각자 커넥션 풀을 잡는다. + * 모든 컨텍스트가 이 컨테이너 하나를 쓰므로 기본 연결 상한(100)을 넘지 않게 늘린다. + */ @ServiceConnection - static final PostgreSQLContainer POSTGRES = new PostgreSQLContainer<>("postgres:16-alpine"); + static final PostgreSQLContainer POSTGRES = new PostgreSQLContainer<>("postgres:16-alpine") + .withCommand("postgres", "-c", "max_connections=500"); static { POSTGRES.start(); @@ -38,4 +51,15 @@ static void jwtSecret(DynamicPropertyRegistry registry) { @Autowired protected MockMvc mockMvc; + + @Autowired + private JdbcTemplate jdbcTemplate; + + @BeforeEach + void resetDatabase() { + List tables = jdbcTemplate.queryForList( + "select tablename from pg_tables where schemaname = 'public'", String.class); + String targets = String.join(", ", tables.stream().filter(t -> !PRESERVED_TABLES.contains(t)).toList()); + jdbcTemplate.execute("TRUNCATE " + targets + " CASCADE"); + } } diff --git a/src/test/java/com/bcsdlab/bcsdinternalapiv2/auth/InitialSetupIntegrationTest.java b/src/test/java/com/bcsdlab/bcsdinternalapiv2/auth/InitialSetupIntegrationTest.java index 82324f9..23b6b45 100644 --- a/src/test/java/com/bcsdlab/bcsdinternalapiv2/auth/InitialSetupIntegrationTest.java +++ b/src/test/java/com/bcsdlab/bcsdinternalapiv2/auth/InitialSetupIntegrationTest.java @@ -6,6 +6,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import com.bcsdlab.bcsdinternalapiv2.IntegrationTestSupport; import com.bcsdlab.bcsdinternalapiv2.auth.model.RefreshToken; import com.bcsdlab.bcsdinternalapiv2.auth.repository.RefreshTokenRepository; import com.bcsdlab.bcsdinternalapiv2.member.model.Member; @@ -24,36 +25,12 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.testcontainers.service.connection.ServiceConnection; -import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc; import org.springframework.http.MediaType; import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.test.context.DynamicPropertyRegistry; -import org.springframework.test.context.DynamicPropertySource; -import org.springframework.test.web.servlet.MockMvc; -import org.testcontainers.containers.PostgreSQLContainer; -import org.testcontainers.junit.jupiter.Container; -import org.testcontainers.junit.jupiter.Testcontainers; - -@Testcontainers -@SpringBootTest -@AutoConfigureMockMvc -class InitialSetupIntegrationTest { - private static final String RAW_PASSWORD = "Temp1234"; - - @Container - @ServiceConnection - static PostgreSQLContainer postgres = new PostgreSQLContainer<>("postgres:16-alpine"); - - @DynamicPropertySource - static void jwtSecret(DynamicPropertyRegistry registry) { - registry.add("app.jwt.secret", () -> "test-only-secret-key-not-for-production-32bytes-min"); - } +class InitialSetupIntegrationTest extends IntegrationTestSupport { - @Autowired - private MockMvc mockMvc; + private static final String RAW_PASSWORD = "Temp1234"; private TrackMaster backend; diff --git a/src/test/java/com/bcsdlab/bcsdinternalapiv2/auth/LoginIntegrationTest.java b/src/test/java/com/bcsdlab/bcsdinternalapiv2/auth/LoginIntegrationTest.java index 15a5704..f7eb8ec 100644 --- a/src/test/java/com/bcsdlab/bcsdinternalapiv2/auth/LoginIntegrationTest.java +++ b/src/test/java/com/bcsdlab/bcsdinternalapiv2/auth/LoginIntegrationTest.java @@ -5,6 +5,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import com.bcsdlab.bcsdinternalapiv2.IntegrationTestSupport; import com.bcsdlab.bcsdinternalapiv2.auth.repository.RefreshTokenRepository; import com.bcsdlab.bcsdinternalapiv2.member.model.Member; import com.bcsdlab.bcsdinternalapiv2.member.model.MemberStatus; @@ -22,36 +23,12 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.testcontainers.service.connection.ServiceConnection; -import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc; import org.springframework.http.MediaType; import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.test.context.DynamicPropertyRegistry; -import org.springframework.test.context.DynamicPropertySource; -import org.springframework.test.web.servlet.MockMvc; -import org.testcontainers.containers.PostgreSQLContainer; -import org.testcontainers.junit.jupiter.Container; -import org.testcontainers.junit.jupiter.Testcontainers; - -@Testcontainers -@SpringBootTest -@AutoConfigureMockMvc -class LoginIntegrationTest { - private static final String RAW_PASSWORD = "Temp1234"; - - @Container - @ServiceConnection - static PostgreSQLContainer postgres = new PostgreSQLContainer<>("postgres:16-alpine"); - - @DynamicPropertySource - static void jwtSecret(DynamicPropertyRegistry registry) { - registry.add("app.jwt.secret", () -> "test-only-secret-key-not-for-production-32bytes-min"); - } +class LoginIntegrationTest extends IntegrationTestSupport { - @Autowired - private MockMvc mockMvc; + private static final String RAW_PASSWORD = "Temp1234"; private TrackMaster backend; diff --git a/src/test/java/com/bcsdlab/bcsdinternalapiv2/auth/PasswordResetIntegrationTest.java b/src/test/java/com/bcsdlab/bcsdinternalapiv2/auth/PasswordResetIntegrationTest.java index f822435..b5844c4 100644 --- a/src/test/java/com/bcsdlab/bcsdinternalapiv2/auth/PasswordResetIntegrationTest.java +++ b/src/test/java/com/bcsdlab/bcsdinternalapiv2/auth/PasswordResetIntegrationTest.java @@ -5,6 +5,7 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import com.bcsdlab.bcsdinternalapiv2.IntegrationTestSupport; import com.bcsdlab.bcsdinternalapiv2.auth.exception.AuthException; import com.bcsdlab.bcsdinternalapiv2.auth.model.PasswordResetToken; import com.bcsdlab.bcsdinternalapiv2.auth.model.RefreshToken; @@ -30,38 +31,14 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.testcontainers.service.connection.ServiceConnection; -import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc; import org.springframework.http.MediaType; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.test.context.DynamicPropertyRegistry; -import org.springframework.test.context.DynamicPropertySource; -import org.springframework.test.web.servlet.MockMvc; -import org.testcontainers.containers.PostgreSQLContainer; -import org.testcontainers.junit.jupiter.Container; -import org.testcontainers.junit.jupiter.Testcontainers; - -@Testcontainers -@SpringBootTest -@AutoConfigureMockMvc -class PasswordResetIntegrationTest { - private static final String RAW_PASSWORD = "Temp1234"; - - @Container - @ServiceConnection - static PostgreSQLContainer postgres = new PostgreSQLContainer<>("postgres:16-alpine"); - - @DynamicPropertySource - static void jwtSecret(DynamicPropertyRegistry registry) { - registry.add("app.jwt.secret", () -> "test-only-secret-key-not-for-production-32bytes-min"); - } +class PasswordResetIntegrationTest extends IntegrationTestSupport { - @Autowired - private MockMvc mockMvc; + private static final String RAW_PASSWORD = "Temp1234"; private TrackMaster backend; diff --git a/src/test/java/com/bcsdlab/bcsdinternalapiv2/auth/RefreshTokenIntegrationTest.java b/src/test/java/com/bcsdlab/bcsdinternalapiv2/auth/RefreshTokenIntegrationTest.java index 38e1b2d..2956140 100644 --- a/src/test/java/com/bcsdlab/bcsdinternalapiv2/auth/RefreshTokenIntegrationTest.java +++ b/src/test/java/com/bcsdlab/bcsdinternalapiv2/auth/RefreshTokenIntegrationTest.java @@ -5,6 +5,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import com.bcsdlab.bcsdinternalapiv2.IntegrationTestSupport; import com.bcsdlab.bcsdinternalapiv2.auth.model.RefreshToken; import com.bcsdlab.bcsdinternalapiv2.auth.repository.RefreshTokenRepository; import com.bcsdlab.bcsdinternalapiv2.member.model.Member; @@ -23,36 +24,12 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.testcontainers.service.connection.ServiceConnection; -import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc; import org.springframework.http.MediaType; import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.test.context.DynamicPropertyRegistry; -import org.springframework.test.context.DynamicPropertySource; -import org.springframework.test.web.servlet.MockMvc; -import org.testcontainers.containers.PostgreSQLContainer; -import org.testcontainers.junit.jupiter.Container; -import org.testcontainers.junit.jupiter.Testcontainers; - -@Testcontainers -@SpringBootTest -@AutoConfigureMockMvc -class RefreshTokenIntegrationTest { - private static final String RAW_PASSWORD = "Temp1234"; - - @Container - @ServiceConnection - static PostgreSQLContainer postgres = new PostgreSQLContainer<>("postgres:16-alpine"); - - @DynamicPropertySource - static void jwtSecret(DynamicPropertyRegistry registry) { - registry.add("app.jwt.secret", () -> "test-only-secret-key-not-for-production-32bytes-min"); - } +class RefreshTokenIntegrationTest extends IntegrationTestSupport { - @Autowired - private MockMvc mockMvc; + private static final String RAW_PASSWORD = "Temp1234"; private TrackMaster backend; diff --git a/src/test/java/com/bcsdlab/bcsdinternalapiv2/member/AdminMemberIntegrationTest.java b/src/test/java/com/bcsdlab/bcsdinternalapiv2/member/AdminMemberIntegrationTest.java index d517784..e3c35be 100644 --- a/src/test/java/com/bcsdlab/bcsdinternalapiv2/member/AdminMemberIntegrationTest.java +++ b/src/test/java/com/bcsdlab/bcsdinternalapiv2/member/AdminMemberIntegrationTest.java @@ -4,6 +4,7 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import com.bcsdlab.bcsdinternalapiv2.IntegrationTestSupport; import com.bcsdlab.bcsdinternalapiv2.member.client.SlackClient; import com.bcsdlab.bcsdinternalapiv2.member.model.AcademicStatus; import com.bcsdlab.bcsdinternalapiv2.member.model.Member; @@ -18,38 +19,14 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.testcontainers.service.connection.ServiceConnection; -import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc; import org.springframework.http.MediaType; import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.test.context.DynamicPropertyRegistry; -import org.springframework.test.context.DynamicPropertySource; import org.springframework.test.context.bean.override.mockito.MockitoBean; -import org.springframework.test.web.servlet.MockMvc; -import org.testcontainers.containers.PostgreSQLContainer; -import org.testcontainers.junit.jupiter.Container; -import org.testcontainers.junit.jupiter.Testcontainers; -@Testcontainers -@SpringBootTest -@AutoConfigureMockMvc -class AdminMemberIntegrationTest { +class AdminMemberIntegrationTest extends IntegrationTestSupport { private static final String RAW_PASSWORD = "Temp1234"; - @Container - @ServiceConnection - static PostgreSQLContainer postgres = new PostgreSQLContainer<>("postgres:16-alpine"); - - @DynamicPropertySource - static void jwtSecret(DynamicPropertyRegistry registry) { - registry.add("app.jwt.secret", () -> "test-only-secret-key-not-for-production-32bytes-min"); - } - - @Autowired - private MockMvc mockMvc; - // 부원 추가가 이메일로 Slack ID를 조회한다 — 테스트에서 실제 slack.com을 부르지 않게 막는다. @MockitoBean private SlackClient slackClient; diff --git a/src/test/java/com/bcsdlab/bcsdinternalapiv2/member/AdminMemberWelcomeMailIntegrationTest.java b/src/test/java/com/bcsdlab/bcsdinternalapiv2/member/AdminMemberWelcomeMailIntegrationTest.java index 6ac0424..ad213ad 100644 --- a/src/test/java/com/bcsdlab/bcsdinternalapiv2/member/AdminMemberWelcomeMailIntegrationTest.java +++ b/src/test/java/com/bcsdlab/bcsdinternalapiv2/member/AdminMemberWelcomeMailIntegrationTest.java @@ -4,6 +4,7 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import com.bcsdlab.bcsdinternalapiv2.IntegrationTestSupport; import com.bcsdlab.bcsdinternalapiv2.member.client.SlackClient; import com.bcsdlab.bcsdinternalapiv2.member.model.Member; import com.bcsdlab.bcsdinternalapiv2.member.model.MemberRole; @@ -18,40 +19,16 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.testcontainers.service.connection.ServiceConnection; -import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc; import org.springframework.http.MediaType; import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.test.context.DynamicPropertyRegistry; -import org.springframework.test.context.DynamicPropertySource; import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.test.context.TestPropertySource; -import org.springframework.test.web.servlet.MockMvc; -import org.testcontainers.containers.PostgreSQLContainer; -import org.testcontainers.junit.jupiter.Container; -import org.testcontainers.junit.jupiter.Testcontainers; - -@Testcontainers -@SpringBootTest -@AutoConfigureMockMvc + @TestPropertySource(properties = "app.mail.transport=log") -class AdminMemberWelcomeMailIntegrationTest { +class AdminMemberWelcomeMailIntegrationTest extends IntegrationTestSupport { private static final String RAW_PASSWORD = "AdminPass1"; - @Container - @ServiceConnection - static PostgreSQLContainer postgres = new PostgreSQLContainer<>("postgres:16-alpine"); - - @DynamicPropertySource - static void jwtSecret(DynamicPropertyRegistry registry) { - registry.add("app.jwt.secret", () -> "test-only-secret-key-not-for-production-32bytes-min"); - } - - @Autowired - private MockMvc mockMvc; - // 부원 추가가 이메일로 Slack ID를 조회한다 — 테스트에서 실제 slack.com을 부르지 않게 막는다. @MockitoBean private SlackClient slackClient; diff --git a/src/test/java/com/bcsdlab/bcsdinternalapiv2/member/MemberDirectoryIntegrationTest.java b/src/test/java/com/bcsdlab/bcsdinternalapiv2/member/MemberDirectoryIntegrationTest.java index 7dd3fe2..44badc8 100644 --- a/src/test/java/com/bcsdlab/bcsdinternalapiv2/member/MemberDirectoryIntegrationTest.java +++ b/src/test/java/com/bcsdlab/bcsdinternalapiv2/member/MemberDirectoryIntegrationTest.java @@ -10,6 +10,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import com.bcsdlab.bcsdinternalapiv2.IntegrationTestSupport; import com.bcsdlab.bcsdinternalapiv2.auth.repository.RefreshTokenRepository; import com.bcsdlab.bcsdinternalapiv2.member.model.AcademicStatus; import com.bcsdlab.bcsdinternalapiv2.member.model.Member; @@ -24,41 +25,17 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.testcontainers.service.connection.ServiceConnection; -import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc; import org.springframework.http.MediaType; import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.test.context.DynamicPropertyRegistry; -import org.springframework.test.context.DynamicPropertySource; import org.springframework.test.context.bean.override.mockito.MockitoBean; -import org.springframework.test.web.servlet.MockMvc; -import org.testcontainers.containers.PostgreSQLContainer; -import org.testcontainers.junit.jupiter.Container; -import org.testcontainers.junit.jupiter.Testcontainers; import software.amazon.awssdk.services.s3.presigner.S3Presigner; import software.amazon.awssdk.services.s3.presigner.model.PresignedPutObjectRequest; import software.amazon.awssdk.services.s3.presigner.model.PutObjectPresignRequest; -@Testcontainers -@SpringBootTest -@AutoConfigureMockMvc -class MemberDirectoryIntegrationTest { +class MemberDirectoryIntegrationTest extends IntegrationTestSupport { private static final String RAW_PASSWORD = "Temp1234"; - @Container - @ServiceConnection - static PostgreSQLContainer postgres = new PostgreSQLContainer<>("postgres:16-alpine"); - - @DynamicPropertySource - static void jwtSecret(DynamicPropertyRegistry registry) { - registry.add("app.jwt.secret", () -> "test-only-secret-key-not-for-production-32bytes-min"); - } - - @Autowired - private MockMvc mockMvc; - @Autowired private MemberRepository memberRepository; diff --git a/src/test/java/com/bcsdlab/bcsdinternalapiv2/reservation/ReservationIntegrationTestSupport.java b/src/test/java/com/bcsdlab/bcsdinternalapiv2/reservation/ReservationIntegrationTestSupport.java index 4084c73..e9d8be8 100644 --- a/src/test/java/com/bcsdlab/bcsdinternalapiv2/reservation/ReservationIntegrationTestSupport.java +++ b/src/test/java/com/bcsdlab/bcsdinternalapiv2/reservation/ReservationIntegrationTestSupport.java @@ -1,5 +1,6 @@ package com.bcsdlab.bcsdinternalapiv2.reservation; +import com.bcsdlab.bcsdinternalapiv2.IntegrationTestSupport; import com.bcsdlab.bcsdinternalapiv2.auth.repository.RefreshTokenRepository; import com.bcsdlab.bcsdinternalapiv2.member.model.Member; import com.bcsdlab.bcsdinternalapiv2.member.model.MemberRole; @@ -12,42 +13,18 @@ import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.BeforeEach; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.testcontainers.service.connection.ServiceConnection; -import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc; import org.springframework.http.MediaType; import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.test.context.DynamicPropertyRegistry; -import org.springframework.test.context.DynamicPropertySource; import org.springframework.test.context.bean.override.mockito.MockitoBean; -import org.springframework.test.web.servlet.MockMvc; -import org.testcontainers.containers.PostgreSQLContainer; -import org.testcontainers.junit.jupiter.Container; -import org.testcontainers.junit.jupiter.Testcontainers; import software.amazon.awssdk.services.s3.presigner.S3Presigner; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -@Testcontainers -@SpringBootTest -@AutoConfigureMockMvc -abstract class ReservationIntegrationTestSupport { +abstract class ReservationIntegrationTestSupport extends IntegrationTestSupport { protected static final String RAW_PASSWORD = "Temp1234"; - @Container - @ServiceConnection - static PostgreSQLContainer postgres = new PostgreSQLContainer<>("postgres:16-alpine"); - - @DynamicPropertySource - static void jwtSecret(DynamicPropertyRegistry registry) { - registry.add("app.jwt.secret", () -> "test-only-secret-key-not-for-production-32bytes-min"); - } - - @Autowired - protected MockMvc mockMvc; - @Autowired protected MemberRepository memberRepository;