diff --git a/back/src/main/java/com/back/global/ai/config/PgVectorContainerConfig.java b/back/src/main/java/com/back/global/ai/config/PgVectorContainerConfig.java index c4b1987..beef7fb 100644 --- a/back/src/main/java/com/back/global/ai/config/PgVectorContainerConfig.java +++ b/back/src/main/java/com/back/global/ai/config/PgVectorContainerConfig.java @@ -1,31 +1,31 @@ -//package com.back.global.ai.config; -// -//import com.zaxxer.hikari.HikariDataSource; -//import org.springframework.context.annotation.*; -//import org.testcontainers.containers.PostgreSQLContainer; -// -//import javax.sql.DataSource; -// -//@Configuration -//@Profile("test") -//public class PgVectorContainerConfig { -// -// @Bean(initMethod = "start", destroyMethod = "stop") -// public PostgreSQLContainer pgContainer() { -// // 여기서 이미지 고정 -// PostgreSQLContainer c = new PostgreSQLContainer<>("pgvector/pgvector:pg16"); -// // 필요하면 파라미터 추가 -// // c.withReuse(true); -// return c; -// } -// -// @Bean -// public DataSource dataSource(PostgreSQLContainer pg) { -// HikariDataSource ds = new HikariDataSource(); -// ds.setJdbcUrl(pg.getJdbcUrl()); -// ds.setUsername(pg.getUsername()); -// ds.setPassword(pg.getPassword()); -// // 드라이버는 Hikari가 JDBC URL로 자동 판단 (org.postgresql.Driver) -// return ds; -// } -//} \ No newline at end of file +package com.back.global.ai.config; + +import com.zaxxer.hikari.HikariDataSource; +import org.springframework.context.annotation.*; +import org.testcontainers.containers.PostgreSQLContainer; + +import javax.sql.DataSource; + +@Configuration +@Profile("test-pg") +public class PgVectorContainerConfig { + + @Bean(initMethod = "start", destroyMethod = "stop") + public PostgreSQLContainer pgContainer() { + // 여기서 이미지 고정 + PostgreSQLContainer c = new PostgreSQLContainer<>("pgvector/pgvector:pg16"); + // 필요하면 파라미터 추가 + // c.withReuse(true); + return c; + } + + @Bean + public DataSource dataSource(PostgreSQLContainer pg) { + HikariDataSource ds = new HikariDataSource(); + ds.setJdbcUrl(pg.getJdbcUrl()); + ds.setUsername(pg.getUsername()); + ds.setPassword(pg.getPassword()); + // 드라이버는 Hikari가 JDBC URL로 자동 판단 (org.postgresql.Driver) + return ds; + } +} \ No newline at end of file diff --git a/back/src/main/java/com/back/global/ai/vector/AIVectorServiceImpl.java b/back/src/main/java/com/back/global/ai/vector/AIVectorServiceImpl.java index f55133f..1532d3b 100644 --- a/back/src/main/java/com/back/global/ai/vector/AIVectorServiceImpl.java +++ b/back/src/main/java/com/back/global/ai/vector/AIVectorServiceImpl.java @@ -19,7 +19,7 @@ import java.util.Map; @Service -@Profile("!test") +@Profile("!test & !test-pg") @RequiredArgsConstructor public class AIVectorServiceImpl implements AIVectorService { diff --git a/back/src/main/java/com/back/global/ai/vector/AIVectorServiceStub.java b/back/src/main/java/com/back/global/ai/vector/AIVectorServiceStub.java index 41c2a0b..623fcab 100644 --- a/back/src/main/java/com/back/global/ai/vector/AIVectorServiceStub.java +++ b/back/src/main/java/com/back/global/ai/vector/AIVectorServiceStub.java @@ -11,7 +11,7 @@ import java.util.List; @Service -@Profile("test") +@Profile({"test", "test-pg"}) public class AIVectorServiceStub implements AIVectorService { // 다음 입력 힌트(상수 또는 null) 반환 diff --git a/back/src/main/java/com/back/global/config/EmbeddedRedisConfig.java b/back/src/main/java/com/back/global/config/EmbeddedRedisConfig.java index af663b0..e0d4cd4 100644 --- a/back/src/main/java/com/back/global/config/EmbeddedRedisConfig.java +++ b/back/src/main/java/com/back/global/config/EmbeddedRedisConfig.java @@ -14,7 +14,7 @@ * - test 프로필에서만 활성화 */ @Configuration -@Profile("test") +@Profile({"test","test-pg"}) public class EmbeddedRedisConfig { @Value("${spring.data.redis.port}") diff --git a/back/src/main/resources/application.yml b/back/src/main/resources/application.yml index 828a65a..2c34b48 100644 --- a/back/src/main/resources/application.yml +++ b/back/src/main/resources/application.yml @@ -10,7 +10,7 @@ spring: flyway: enabled: false profiles: - active: test + active: test-pg output: ansi: enabled: always diff --git a/back/src/test/java/com/back/domain/comment/controller/CommentControllerTest.java b/back/src/test/java/com/back/domain/comment/controller/CommentControllerTest.java index 714a975..83a5308 100644 --- a/back/src/test/java/com/back/domain/comment/controller/CommentControllerTest.java +++ b/back/src/test/java/com/back/domain/comment/controller/CommentControllerTest.java @@ -23,7 +23,6 @@ import org.springframework.http.MediaType; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.jdbc.Sql; import org.springframework.test.context.jdbc.SqlConfig; import org.springframework.test.web.servlet.MockMvc; @@ -39,26 +38,20 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -@ActiveProfiles("test") + @SpringBootTest @AutoConfigureMockMvc(addFilters = false) @SqlConfig(transactionMode = SqlConfig.TransactionMode.ISOLATED) @Sql( statements = { - "SET REFERENTIAL_INTEGRITY FALSE", - "TRUNCATE TABLE COMMENTS", - "TRUNCATE TABLE POST", - "TRUNCATE TABLE USERS", - - "ALTER TABLE COMMENTS ALTER COLUMN id RESTART WITH 1", - "ALTER TABLE POST ALTER COLUMN id RESTART WITH 1", - "ALTER TABLE USERS ALTER COLUMN id RESTART WITH 1", - "SET REFERENTIAL_INTEGRITY TRUE" + "TRUNCATE TABLE public.comments, public.post, public.users RESTART IDENTITY CASCADE" }, executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD ) + class CommentControllerTest { + @Autowired private UserRepository userRepository; @Autowired private PostRepository postRepository; @Autowired private CommentRepository commentRepository; diff --git a/back/src/test/java/com/back/domain/like/controller/LikeControllerTest.java b/back/src/test/java/com/back/domain/like/controller/LikeControllerTest.java index 33b9cfe..9e75893 100644 --- a/back/src/test/java/com/back/domain/like/controller/LikeControllerTest.java +++ b/back/src/test/java/com/back/domain/like/controller/LikeControllerTest.java @@ -24,7 +24,6 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.jdbc.Sql; import org.springframework.test.context.jdbc.SqlConfig; import org.springframework.test.web.servlet.MockMvc; @@ -47,22 +46,10 @@ @SqlConfig(transactionMode = SqlConfig.TransactionMode.ISOLATED) @Sql( statements = { - "SET REFERENTIAL_INTEGRITY FALSE", - "TRUNCATE TABLE COMMENT_LIKES", - "TRUNCATE TABLE COMMENTS", - "TRUNCATE TABLE POST_LIKES", - "TRUNCATE TABLE POST", - "TRUNCATE TABLE USERS", - "ALTER TABLE COMMENT_LIKES ALTER COLUMN ID RESTART WITH 1", - "ALTER TABLE COMMENTS ALTER COLUMN ID RESTART WITH 1", - "ALTER TABLE POST_LIKES ALTER COLUMN ID RESTART WITH 1", - "ALTER TABLE POST ALTER COLUMN ID RESTART WITH 1", - "ALTER TABLE USERS ALTER COLUMN ID RESTART WITH 1", - "SET REFERENTIAL_INTEGRITY TRUE" + "TRUNCATE TABLE public.comment_likes, public.comments, public.post_likes, public.post, public.users RESTART IDENTITY CASCADE" }, executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD ) -@ActiveProfiles("test") @SpringBootTest @AutoConfigureMockMvc(addFilters = false) class LikeControllerTest { diff --git a/back/src/test/java/com/back/domain/node/controller/BaseLineControllerTest.java b/back/src/test/java/com/back/domain/node/controller/BaseLineControllerTest.java index 40258b3..10fa8da 100644 --- a/back/src/test/java/com/back/domain/node/controller/BaseLineControllerTest.java +++ b/back/src/test/java/com/back/domain/node/controller/BaseLineControllerTest.java @@ -25,6 +25,7 @@ import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.context.SecurityContext; import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.jdbc.Sql; import org.springframework.test.context.jdbc.SqlConfig; import org.springframework.test.web.servlet.MockMvc; @@ -43,6 +44,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @SpringBootTest +@ActiveProfiles("test") @AutoConfigureMockMvc(addFilters = true) @TestInstance(TestInstance.Lifecycle.PER_CLASS) @DisplayName("Re:Life — BaseLine/BaseNode 통합 테스트 (보안 일괄 적용)") diff --git a/back/src/test/java/com/back/domain/node/controller/DecisionLineControllerTest.java b/back/src/test/java/com/back/domain/node/controller/DecisionLineControllerTest.java index 2ba295d..f1267e2 100644 --- a/back/src/test/java/com/back/domain/node/controller/DecisionLineControllerTest.java +++ b/back/src/test/java/com/back/domain/node/controller/DecisionLineControllerTest.java @@ -24,6 +24,7 @@ import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.http.MediaType; +import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.jdbc.Sql; import org.springframework.test.context.jdbc.SqlConfig; import org.springframework.test.web.servlet.MockMvc; @@ -40,6 +41,7 @@ import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; @SpringBootTest +@ActiveProfiles("test") @AutoConfigureMockMvc(addFilters = true) // ★ 필터 활성화 @TestInstance(TestInstance.Lifecycle.PER_CLASS) @DisplayName("Re:Life — DecisionLine 조회(목록·상세) 통합 테스트") diff --git a/back/src/test/java/com/back/domain/node/controller/SecurityAndErrorPayloadTest.java b/back/src/test/java/com/back/domain/node/controller/SecurityAndErrorPayloadTest.java index b41e5c4..69113ad 100644 --- a/back/src/test/java/com/back/domain/node/controller/SecurityAndErrorPayloadTest.java +++ b/back/src/test/java/com/back/domain/node/controller/SecurityAndErrorPayloadTest.java @@ -12,6 +12,7 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.http.MediaType; import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.jdbc.Sql; import org.springframework.test.context.jdbc.SqlConfig; import org.springframework.test.web.servlet.MockMvc; @@ -26,6 +27,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; @SpringBootTest +@ActiveProfiles("test") @AutoConfigureMockMvc(addFilters = true) @TestInstance(TestInstance.Lifecycle.PER_CLASS) @DisplayName("Re:Life — 인증/권한 & 오류 페이로드") diff --git a/back/src/test/java/com/back/domain/poll/controller/PollVoteControllerTest.java b/back/src/test/java/com/back/domain/poll/controller/PollVoteControllerTest.java index 65b4e18..a06551b 100644 --- a/back/src/test/java/com/back/domain/poll/controller/PollVoteControllerTest.java +++ b/back/src/test/java/com/back/domain/poll/controller/PollVoteControllerTest.java @@ -40,16 +40,7 @@ @SqlConfig(transactionMode = SqlConfig.TransactionMode.ISOLATED) @Sql( statements = { - "SET REFERENTIAL_INTEGRITY FALSE", - "TRUNCATE TABLE POLL_VOTES", - "TRUNCATE TABLE COMMENTS", - "TRUNCATE TABLE POST", - "TRUNCATE TABLE USERS", - "ALTER TABLE POLL_VOTES ALTER COLUMN ID RESTART WITH 1", - "ALTER TABLE COMMENTS ALTER COLUMN ID RESTART WITH 1", - "ALTER TABLE POST ALTER COLUMN ID RESTART WITH 1", - "ALTER TABLE USERS ALTER COLUMN ID RESTART WITH 1", - "SET REFERENTIAL_INTEGRITY TRUE" + "TRUNCATE TABLE public.poll_votes, public.comments, public.post, public.users RESTART IDENTITY CASCADE" }, executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD ) diff --git a/back/src/test/java/com/back/domain/post/controller/PostControllerTest.java b/back/src/test/java/com/back/domain/post/controller/PostControllerTest.java index 0d89be4..0252343 100644 --- a/back/src/test/java/com/back/domain/post/controller/PostControllerTest.java +++ b/back/src/test/java/com/back/domain/post/controller/PostControllerTest.java @@ -24,7 +24,6 @@ import org.springframework.http.MediaType; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.jdbc.Sql; import org.springframework.test.context.jdbc.SqlConfig; import org.springframework.test.web.servlet.MockMvc; @@ -36,21 +35,13 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -@ActiveProfiles("test") + @SpringBootTest @AutoConfigureMockMvc(addFilters = false) @SqlConfig(transactionMode = SqlConfig.TransactionMode.ISOLATED) @Sql( statements = { - "SET REFERENTIAL_INTEGRITY FALSE", - "TRUNCATE TABLE COMMENTS", - "TRUNCATE TABLE POST", - "TRUNCATE TABLE USERS", - - "ALTER TABLE COMMENTS ALTER COLUMN id RESTART WITH 1", - "ALTER TABLE POST ALTER COLUMN id RESTART WITH 1", - "ALTER TABLE USERS ALTER COLUMN id RESTART WITH 1", - "SET REFERENTIAL_INTEGRITY TRUE" + "TRUNCATE TABLE public.comments, public.post, public.users RESTART IDENTITY CASCADE" }, executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD ) diff --git a/back/src/test/java/com/back/domain/scenario/service/ScenarioServiceTest.java b/back/src/test/java/com/back/domain/scenario/service/ScenarioServiceTest.java index fab851e..7561d43 100644 --- a/back/src/test/java/com/back/domain/scenario/service/ScenarioServiceTest.java +++ b/back/src/test/java/com/back/domain/scenario/service/ScenarioServiceTest.java @@ -9,8 +9,6 @@ import com.back.domain.scenario.entity.ScenarioStatus; import com.back.domain.scenario.repository.ScenarioRepository; import com.back.domain.user.entity.User; -import com.back.global.ai.dto.result.DecisionScenarioResult; -import com.back.global.ai.service.AiService; import com.back.global.exception.ApiException; import com.back.global.exception.ErrorCode; import com.fasterxml.jackson.core.type.TypeReference; @@ -21,13 +19,12 @@ import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.Spy; import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.test.context.ActiveProfiles; import org.springframework.test.util.ReflectionTestUtils; import java.util.Map; import java.util.Optional; -import java.util.concurrent.CompletableFuture; import static org.assertj.core.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; @@ -39,6 +36,7 @@ */ @ExtendWith(MockitoExtension.class) @DisplayName("ScenarioService 단위 테스트") +@ActiveProfiles("test") class ScenarioServiceTest { @Mock private ScenarioRepository scenarioRepository; diff --git a/back/src/test/java/com/back/global/ai/client/image/StableDiffusionImageClientTest.java b/back/src/test/java/com/back/global/ai/client/image/StableDiffusionImageClientTest.java index 17ca39c..1563d29 100644 --- a/back/src/test/java/com/back/global/ai/client/image/StableDiffusionImageClientTest.java +++ b/back/src/test/java/com/back/global/ai/client/image/StableDiffusionImageClientTest.java @@ -11,6 +11,7 @@ import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.test.context.ActiveProfiles; import org.springframework.web.reactive.function.client.WebClient; import reactor.core.publisher.Mono; @@ -27,6 +28,7 @@ * Stable Diffusion API 연동 로직을 검증합니다. */ @ExtendWith(MockitoExtension.class) +@ActiveProfiles("test") @DisplayName("StableDiffusionImageClient 단위 테스트") class StableDiffusionImageClientTest { diff --git a/back/src/test/java/com/back/global/ai/service/AiServiceImplTest.java b/back/src/test/java/com/back/global/ai/service/AiServiceImplTest.java index bcc0989..3992f2b 100644 --- a/back/src/test/java/com/back/global/ai/service/AiServiceImplTest.java +++ b/back/src/test/java/com/back/global/ai/service/AiServiceImplTest.java @@ -28,11 +28,11 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.test.context.ActiveProfiles; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; -import java.util.Map; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; @@ -47,6 +47,7 @@ * Mock을 사용하여 AI 클라이언트 및 의존성을 격리한 테스트를 수행합니다. */ @ExtendWith(MockitoExtension.class) +@ActiveProfiles("test") @DisplayName("AiServiceImpl 테스트") class AiServiceImplTest { diff --git a/back/src/test/java/com/back/global/config/JsonConfigTest.java b/back/src/test/java/com/back/global/config/JsonConfigTest.java index f4682c8..97961a8 100644 --- a/back/src/test/java/com/back/global/config/JsonConfigTest.java +++ b/back/src/test/java/com/back/global/config/JsonConfigTest.java @@ -8,6 +8,7 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.TestPropertySource; import java.time.LocalDateTime; @@ -20,6 +21,7 @@ * Spring Boot 통합 테스트로 실제 Bean이 정상적으로 동작하는지 검증합니다. */ @SpringBootTest +@ActiveProfiles("test") @TestPropertySource(properties = "spring.profiles.active=test") @DisplayName("JsonConfig 및 ObjectMapper 테스트") class JsonConfigTest { diff --git a/back/src/test/java/com/back/global/storage/LocalStorageServiceTest.java b/back/src/test/java/com/back/global/storage/LocalStorageServiceTest.java index 16d3417..72e8db7 100644 --- a/back/src/test/java/com/back/global/storage/LocalStorageServiceTest.java +++ b/back/src/test/java/com/back/global/storage/LocalStorageServiceTest.java @@ -12,6 +12,7 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.test.context.ActiveProfiles; import java.io.IOException; import java.nio.file.Files; @@ -29,6 +30,7 @@ * 로컬 파일 시스템 기반 이미지 저장 로직을 검증합니다. */ @ExtendWith(MockitoExtension.class) +@ActiveProfiles("test") @DisplayName("LocalStorageService 단위 테스트") class LocalStorageServiceTest { diff --git a/back/src/test/java/com/back/global/storage/S3StorageServiceTest.java b/back/src/test/java/com/back/global/storage/S3StorageServiceTest.java index c9003bb..bbe6cf1 100644 --- a/back/src/test/java/com/back/global/storage/S3StorageServiceTest.java +++ b/back/src/test/java/com/back/global/storage/S3StorageServiceTest.java @@ -11,30 +11,27 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.test.context.ActiveProfiles; import software.amazon.awssdk.awscore.exception.AwsErrorDetails; import software.amazon.awssdk.core.sync.RequestBody; import software.amazon.awssdk.services.s3.S3Client; -import software.amazon.awssdk.services.s3.model.DeleteObjectRequest; -import software.amazon.awssdk.services.s3.model.PutObjectRequest; -import software.amazon.awssdk.services.s3.model.S3Exception; +import software.amazon.awssdk.services.s3.model.*; import java.util.Base64; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; -import software.amazon.awssdk.services.s3.model.DeleteObjectResponse; -import software.amazon.awssdk.services.s3.model.PutObjectResponse; - -import static org.assertj.core.api.Assertions.*; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.ArgumentMatchers.any; import static org.mockito.BDDMockito.*; -import static org.mockito.Mockito.*; /** * S3StorageService 단위 테스트. * AWS S3 기반 이미지 저장 로직을 검증합니다. */ @ExtendWith(MockitoExtension.class) +@ActiveProfiles("test") @DisplayName("S3StorageService 단위 테스트") class S3StorageServiceTest {