From de47a44d04d70ee12ee6f0ef054497daffe4c681 Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 3 Dec 2025 10:40:58 +1100 Subject: [PATCH 1/3] Refactor test container, define @IntegrationTest and @DataJpaIntegrationTest --- .../config/DataJpaIntegrationTest.java | 20 +++++++ .../org/nkcoder/config/IntegrationTest.java | 19 +++++++ .../org/nkcoder/{ => config}/TestConfig.java | 2 +- .../config/TestContainersConfiguration.java | 21 ++++++++ .../controller/BaseControllerTest.java | 2 +- .../integration/AuthFlowIntegrationTest.java | 15 +++++- .../integration/BaseIntegrationTest.java | 53 ------------------- .../repository/BaseRepositoryTest.java | 50 ----------------- .../RefreshTokenRepositoryTest.java | 4 +- .../repository/UserRepositoryTest.java | 4 +- src/test/resources/application-test.yml | 2 + 11 files changed, 84 insertions(+), 108 deletions(-) create mode 100644 src/test/java/org/nkcoder/config/DataJpaIntegrationTest.java create mode 100644 src/test/java/org/nkcoder/config/IntegrationTest.java rename src/test/java/org/nkcoder/{ => config}/TestConfig.java (98%) create mode 100644 src/test/java/org/nkcoder/config/TestContainersConfiguration.java delete mode 100644 src/test/java/org/nkcoder/integration/BaseIntegrationTest.java delete mode 100644 src/test/java/org/nkcoder/repository/BaseRepositoryTest.java diff --git a/src/test/java/org/nkcoder/config/DataJpaIntegrationTest.java b/src/test/java/org/nkcoder/config/DataJpaIntegrationTest.java new file mode 100644 index 0000000..7da53ee --- /dev/null +++ b/src/test/java/org/nkcoder/config/DataJpaIntegrationTest.java @@ -0,0 +1,20 @@ +package org.nkcoder.config; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.context.annotation.Import; +import org.springframework.data.jpa.repository.config.EnableJpaAuditing; +import org.springframework.test.context.ActiveProfiles; + +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +@DataJpaTest +@Import(TestContainersConfiguration.class) +@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) +@ActiveProfiles("test") +@EnableJpaAuditing +public @interface DataJpaIntegrationTest {} diff --git a/src/test/java/org/nkcoder/config/IntegrationTest.java b/src/test/java/org/nkcoder/config/IntegrationTest.java new file mode 100644 index 0000000..a4f8d84 --- /dev/null +++ b/src/test/java/org/nkcoder/config/IntegrationTest.java @@ -0,0 +1,19 @@ +package org.nkcoder.config; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.context.annotation.Import; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.transaction.annotation.Transactional; + +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) +@Import(TestContainersConfiguration.class) +@ActiveProfiles("test") +@Transactional // Auto-rollback after each test +public @interface IntegrationTest {} diff --git a/src/test/java/org/nkcoder/TestConfig.java b/src/test/java/org/nkcoder/config/TestConfig.java similarity index 98% rename from src/test/java/org/nkcoder/TestConfig.java rename to src/test/java/org/nkcoder/config/TestConfig.java index 56fa1be..0105bb0 100644 --- a/src/test/java/org/nkcoder/TestConfig.java +++ b/src/test/java/org/nkcoder/config/TestConfig.java @@ -1,4 +1,4 @@ -package org.nkcoder; +package org.nkcoder.config; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.PropertyNamingStrategies; diff --git a/src/test/java/org/nkcoder/config/TestContainersConfiguration.java b/src/test/java/org/nkcoder/config/TestContainersConfiguration.java new file mode 100644 index 0000000..285813c --- /dev/null +++ b/src/test/java/org/nkcoder/config/TestContainersConfiguration.java @@ -0,0 +1,21 @@ +package org.nkcoder.config; + +import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.boot.testcontainers.service.connection.ServiceConnection; +import org.springframework.context.annotation.Bean; +import org.testcontainers.containers.PostgreSQLContainer; + +@TestConfiguration(proxyBeanMethods = false) +public class TestContainersConfiguration { + private static final String POSTGRES_IMAGE = "postgres:17-alpine"; + + @Bean + @ServiceConnection + PostgreSQLContainer postgresContainer() { + return new PostgreSQLContainer<>(POSTGRES_IMAGE) + .withDatabaseName("test-db") + .withUsername("test") + .withPassword("test") + .withReuse(true); + } +} diff --git a/src/test/java/org/nkcoder/controller/BaseControllerTest.java b/src/test/java/org/nkcoder/controller/BaseControllerTest.java index 8113d7e..2b665ef 100644 --- a/src/test/java/org/nkcoder/controller/BaseControllerTest.java +++ b/src/test/java/org/nkcoder/controller/BaseControllerTest.java @@ -1,8 +1,8 @@ package org.nkcoder.controller; import com.fasterxml.jackson.databind.ObjectMapper; -import org.nkcoder.TestConfig; import org.nkcoder.config.JpaAuditingConfig; +import org.nkcoder.config.TestConfig; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; diff --git a/src/test/java/org/nkcoder/integration/AuthFlowIntegrationTest.java b/src/test/java/org/nkcoder/integration/AuthFlowIntegrationTest.java index fd9b46b..5f8d133 100644 --- a/src/test/java/org/nkcoder/integration/AuthFlowIntegrationTest.java +++ b/src/test/java/org/nkcoder/integration/AuthFlowIntegrationTest.java @@ -3,14 +3,27 @@ import static io.restassured.RestAssured.given; import static org.hamcrest.Matchers.*; +import io.restassured.RestAssured; import io.restassured.http.ContentType; import io.restassured.response.Response; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; +import org.nkcoder.config.IntegrationTest; +import org.springframework.boot.test.web.server.LocalServerPort; +@IntegrationTest @DisplayName("Auth Flow Integration Tests") -class AuthFlowIntegrationTest extends BaseIntegrationTest { +class AuthFlowIntegrationTest { + + @LocalServerPort private int port; + + @BeforeEach + void setupRestAssured() { + RestAssured.port = port; + RestAssured.basePath = "/api/users"; + } @Nested @DisplayName("Complete Authentication Flow") diff --git a/src/test/java/org/nkcoder/integration/BaseIntegrationTest.java b/src/test/java/org/nkcoder/integration/BaseIntegrationTest.java deleted file mode 100644 index 999decf..0000000 --- a/src/test/java/org/nkcoder/integration/BaseIntegrationTest.java +++ /dev/null @@ -1,53 +0,0 @@ -package org.nkcoder.integration; - -import io.restassured.RestAssured; -import org.junit.jupiter.api.BeforeEach; -import org.nkcoder.repository.RefreshTokenRepository; -import org.nkcoder.repository.UserRepository; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.server.LocalServerPort; -import org.springframework.test.context.ActiveProfiles; -import org.springframework.test.context.DynamicPropertyRegistry; -import org.springframework.test.context.DynamicPropertySource; -import org.testcontainers.containers.PostgreSQLContainer; - -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) -@ActiveProfiles("test") -public class BaseIntegrationTest { - // Singleton container - shared across all integration tests - static PostgreSQLContainer postgres; - - static { - postgres = - new PostgreSQLContainer<>("postgres:17") - .withDatabaseName("testdb") - .withUsername("test") - .withPassword("test"); - postgres.start(); - } - - @DynamicPropertySource - static void configureProperties(DynamicPropertyRegistry registry) { - registry.add("spring.datasource.url", postgres::getJdbcUrl); - registry.add("spring.datasource.username", postgres::getUsername); - registry.add("spring.datasource.password", postgres::getPassword); - } - - @LocalServerPort protected int port; - - @Autowired protected UserRepository userRepository; - @Autowired protected RefreshTokenRepository refreshTokenRepository; - - @BeforeEach - void setupRestAssured() { - RestAssured.port = port; - RestAssured.basePath = "/api/users"; - } - - @BeforeEach - void cleanDatabase() { - userRepository.deleteAll(); - refreshTokenRepository.deleteAll(); - } -} diff --git a/src/test/java/org/nkcoder/repository/BaseRepositoryTest.java b/src/test/java/org/nkcoder/repository/BaseRepositoryTest.java deleted file mode 100644 index 11871d9..0000000 --- a/src/test/java/org/nkcoder/repository/BaseRepositoryTest.java +++ /dev/null @@ -1,50 +0,0 @@ -package org.nkcoder.repository; - -import org.nkcoder.config.JpaAuditingConfig; -import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; -import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; -import org.springframework.context.annotation.Import; -import org.springframework.test.context.ActiveProfiles; -import org.springframework.test.context.DynamicPropertyRegistry; -import org.springframework.test.context.DynamicPropertySource; -import org.testcontainers.containers.PostgreSQLContainer; -import org.testcontainers.junit.jupiter.Testcontainers; - -// Loads only JPA components (entities, repositories), much faster than @SpringBootTest -@DataJpaTest -@Testcontainers -// @CreatedDate and @LastModifiedDate only works when Spring Data JPA auditing is enabled -@Import(JpaAuditingConfig.class) -@ActiveProfiles("test") -// Prevents Spring from replacing our PostgreSQL with H2 -@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) -public class BaseRepositoryTest { - - /** - * Singleton container - NO @Container and @ServiceConnection annotation! - * - *
-   * With the @Container annotation on a static field in a base class:
-   * - Each subclass gets its own container lifecycle management
-   * - Containers may start/stop unpredictably when tests run in parallel
-   * - Connection errors occur when one test class's container is stopped while another is still running
-   * 
- */ - static PostgreSQLContainer postgres; - - static { - postgres = - new PostgreSQLContainer<>("postgres:17") - .withDatabaseName("testdb") - .withUsername("test") - .withPassword("test"); - postgres.start(); // Started once, never stopped until JVM exits - } - - @DynamicPropertySource - static void configureProperties(DynamicPropertyRegistry registry) { - registry.add("spring.datasource.url", postgres::getJdbcUrl); - registry.add("spring.datasource.username", postgres::getUsername); - registry.add("spring.datasource.password", postgres::getPassword); - } -} diff --git a/src/test/java/org/nkcoder/repository/RefreshTokenRepositoryTest.java b/src/test/java/org/nkcoder/repository/RefreshTokenRepositoryTest.java index c7201d8..4e89a6b 100644 --- a/src/test/java/org/nkcoder/repository/RefreshTokenRepositoryTest.java +++ b/src/test/java/org/nkcoder/repository/RefreshTokenRepositoryTest.java @@ -9,14 +9,16 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; +import org.nkcoder.config.DataJpaIntegrationTest; import org.nkcoder.entity.RefreshToken; import org.nkcoder.entity.User; import org.nkcoder.enums.Role; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager; +@DataJpaIntegrationTest @DisplayName("RefreshTokenRepository") -class RefreshTokenRepositoryTest extends BaseRepositoryTest { +class RefreshTokenRepositoryTest { @Autowired private RefreshTokenRepository refreshTokenRepository; @Autowired private UserRepository userRepository; diff --git a/src/test/java/org/nkcoder/repository/UserRepositoryTest.java b/src/test/java/org/nkcoder/repository/UserRepositoryTest.java index 3ddd3e1..dcf1bbc 100644 --- a/src/test/java/org/nkcoder/repository/UserRepositoryTest.java +++ b/src/test/java/org/nkcoder/repository/UserRepositoryTest.java @@ -10,13 +10,15 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; +import org.nkcoder.config.DataJpaIntegrationTest; import org.nkcoder.entity.User; import org.nkcoder.enums.Role; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager; +@DataJpaIntegrationTest @DisplayName("UserRepository") -public class UserRepositoryTest extends BaseRepositoryTest { +public class UserRepositoryTest { @Autowired private UserRepository userRepository; // JPA-aware test utility for persist/flush/clear operations @Autowired private TestEntityManager entityManager; diff --git a/src/test/resources/application-test.yml b/src/test/resources/application-test.yml index 84f6fba..8c95dc4 100644 --- a/src/test/resources/application-test.yml +++ b/src/test/resources/application-test.yml @@ -10,6 +10,8 @@ spring: hibernate: # Hibernate validates entity mappings against the actual schema created by Flyway, catching mapping errors early ddl-auto: validate + # faster tests + open-in-view: false flyway: # Run migrations in tests to match production schema From 2d1813f78826a8026f2d34f34ab5906930838ee8 Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 3 Dec 2025 11:11:10 +1100 Subject: [PATCH 2/3] Refactor the controller tests, remove TestConfig --- .../config/DataJpaIntegrationTest.java | 3 +- .../org/nkcoder/config/IntegrationTest.java | 5 +++ .../java/org/nkcoder/config/TestConfig.java | 45 ------------------- .../config/TestContainersConfiguration.java | 24 ++++++++++ .../controller/AuthControllerTest.java | 13 +++--- .../controller/BaseControllerTest.java | 6 +-- .../controller/UserControllerTest.java | 10 +---- 7 files changed, 41 insertions(+), 65 deletions(-) delete mode 100644 src/test/java/org/nkcoder/config/TestConfig.java diff --git a/src/test/java/org/nkcoder/config/DataJpaIntegrationTest.java b/src/test/java/org/nkcoder/config/DataJpaIntegrationTest.java index 7da53ee..8fd8cc9 100644 --- a/src/test/java/org/nkcoder/config/DataJpaIntegrationTest.java +++ b/src/test/java/org/nkcoder/config/DataJpaIntegrationTest.java @@ -10,11 +10,12 @@ import org.springframework.data.jpa.repository.config.EnableJpaAuditing; import org.springframework.test.context.ActiveProfiles; +/** Why @EnableJpaAuditing: because @CreatedDate and @LastModifiedDate is set by JPA auditing. */ @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @DataJpaTest @Import(TestContainersConfiguration.class) @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) @ActiveProfiles("test") -@EnableJpaAuditing +@EnableJpaAuditing // public @interface DataJpaIntegrationTest {} diff --git a/src/test/java/org/nkcoder/config/IntegrationTest.java b/src/test/java/org/nkcoder/config/IntegrationTest.java index a4f8d84..b52e3e2 100644 --- a/src/test/java/org/nkcoder/config/IntegrationTest.java +++ b/src/test/java/org/nkcoder/config/IntegrationTest.java @@ -10,6 +10,11 @@ import org.springframework.test.context.ActiveProfiles; import org.springframework.transaction.annotation.Transactional; +/** + * Note: @SpringBootTest performs full component scanning and will include the {@link + * JpaAuditingConfig} and enable JPA auditing. So don't add @EnableJPAAuditing on this annotation, + * otherwise it will be registered multiple times during AOT processing. + */ @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) diff --git a/src/test/java/org/nkcoder/config/TestConfig.java b/src/test/java/org/nkcoder/config/TestConfig.java deleted file mode 100644 index 0105bb0..0000000 --- a/src/test/java/org/nkcoder/config/TestConfig.java +++ /dev/null @@ -1,45 +0,0 @@ -package org.nkcoder.config; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.PropertyNamingStrategies; -import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; -import org.springframework.boot.test.context.TestConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Primary; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; -import org.springframework.security.web.SecurityFilterChain; - -@TestConfiguration -public class TestConfig { - @Bean - @Primary - public ObjectMapper objectMapper() { - return new ObjectMapper() - .registerModule(new JavaTimeModule()) - .setPropertyNamingStrategy((PropertyNamingStrategies.LOWER_CAMEL_CASE)); - } - - @TestConfiguration - @EnableWebSecurity - public static class TestSecurityConfig { - @Bean - public SecurityFilterChain testSecurityFilterChain(HttpSecurity http) throws Exception { - return http.csrf(AbstractHttpConfigurer::disable) - .authorizeHttpRequests( - authorize -> - authorize - .requestMatchers( - "/api/users/auth/register", - "/api/users/auth/login", - "/api/users/auth/refresh", - "/api/users/auth/logout", - "/api/users/auth/logout-single") - .permitAll() - .anyRequest() - .authenticated()) - .build(); - } - } -} diff --git a/src/test/java/org/nkcoder/config/TestContainersConfiguration.java b/src/test/java/org/nkcoder/config/TestContainersConfiguration.java index 285813c..2f633d4 100644 --- a/src/test/java/org/nkcoder/config/TestContainersConfiguration.java +++ b/src/test/java/org/nkcoder/config/TestContainersConfiguration.java @@ -5,6 +5,30 @@ import org.springframework.context.annotation.Bean; import org.testcontainers.containers.PostgreSQLContainer; +/** + * The @TestConfiguration with @ServiceConnection and a reusable PostgreSQL container is the modern, + * Spring Boot 3.1+ recommended pattern for integration tests. Centralized Testcontainers + * configuration for all integration tests. + * + *

Why this approach is recommended: + * + *

+ * + *

Usage: Import this config in your test classes with: + * + *

@Import(TestContainersConfiguration.class)
+ * + * or apply via a custom meta-annotation like @IntegrationTest. + */ @TestConfiguration(proxyBeanMethods = false) public class TestContainersConfiguration { private static final String POSTGRES_IMAGE = "postgres:17-alpine"; diff --git a/src/test/java/org/nkcoder/controller/AuthControllerTest.java b/src/test/java/org/nkcoder/controller/AuthControllerTest.java index 769798b..178aef4 100644 --- a/src/test/java/org/nkcoder/controller/AuthControllerTest.java +++ b/src/test/java/org/nkcoder/controller/AuthControllerTest.java @@ -25,18 +25,17 @@ import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.FilterType; import org.springframework.http.MediaType; -import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.bean.override.mockito.MockitoBean; @DisplayName("AuthController tests") -@ActiveProfiles("test") @WebMvcTest( - value = AuthController.class, + controllers = AuthController.class, excludeAutoConfiguration = {SecurityAutoConfiguration.class}, - excludeFilters = - @ComponentScan.Filter( - type = FilterType.ASSIGNABLE_TYPE, - classes = JwtAuthenticationFilter.class)) + excludeFilters = { + @ComponentScan.Filter( + type = FilterType.ASSIGNABLE_TYPE, + classes = {JwtAuthenticationFilter.class}) + }) class AuthControllerTest extends BaseControllerTest { @MockitoBean private AuthService authService; diff --git a/src/test/java/org/nkcoder/controller/BaseControllerTest.java b/src/test/java/org/nkcoder/controller/BaseControllerTest.java index 2b665ef..f0c96b7 100644 --- a/src/test/java/org/nkcoder/controller/BaseControllerTest.java +++ b/src/test/java/org/nkcoder/controller/BaseControllerTest.java @@ -2,16 +2,14 @@ import com.fasterxml.jackson.databind.ObjectMapper; import org.nkcoder.config.JpaAuditingConfig; -import org.nkcoder.config.TestConfig; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; -import org.springframework.context.annotation.Import; import org.springframework.test.web.servlet.MockMvc; -@WebMvcTest -@Import(TestConfig.class) +/** Base class for controller slice tests. */ @ImportAutoConfiguration(exclude = {JpaAuditingConfig.class}) +@WebMvcTest public class BaseControllerTest { @Autowired protected ObjectMapper objectMapper; diff --git a/src/test/java/org/nkcoder/controller/UserControllerTest.java b/src/test/java/org/nkcoder/controller/UserControllerTest.java index 3e7f54b..7b9c130 100644 --- a/src/test/java/org/nkcoder/controller/UserControllerTest.java +++ b/src/test/java/org/nkcoder/controller/UserControllerTest.java @@ -15,12 +15,10 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; -import org.nkcoder.config.SecurityConfig; import org.nkcoder.dto.user.ChangePasswordRequest; import org.nkcoder.dto.user.UpdateProfileRequest; import org.nkcoder.dto.user.UserResponse; import org.nkcoder.enums.Role; -import org.nkcoder.security.JwtAuthenticationEntryPoint; import org.nkcoder.security.JwtAuthenticationFilter; import org.nkcoder.service.UserService; import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; @@ -33,16 +31,12 @@ @DisplayName("UserController tests") @WebMvcTest( - value = UserController.class, + controllers = UserController.class, excludeAutoConfiguration = {SecurityAutoConfiguration.class}, excludeFilters = { @ComponentScan.Filter( type = FilterType.ASSIGNABLE_TYPE, - classes = { - JwtAuthenticationFilter.class, - SecurityConfig.class, - JwtAuthenticationEntryPoint.class - }) + classes = {JwtAuthenticationFilter.class}) }) class UserControllerTest extends BaseControllerTest { From dc84b952ae6ab70cca2d819f1fdd0275bdcd7223 Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 3 Dec 2025 11:15:36 +1100 Subject: [PATCH 3/3] Rename to AuthControllerIntegrationTest and move to integration/ --- .../AuthControllerIntegrationTest.java} | 32 +++---------------- 1 file changed, 4 insertions(+), 28 deletions(-) rename src/test/java/org/nkcoder/{controller/AuthControllerSecurityTest.java => integration/AuthControllerIntegrationTest.java} (85%) diff --git a/src/test/java/org/nkcoder/controller/AuthControllerSecurityTest.java b/src/test/java/org/nkcoder/integration/AuthControllerIntegrationTest.java similarity index 85% rename from src/test/java/org/nkcoder/controller/AuthControllerSecurityTest.java rename to src/test/java/org/nkcoder/integration/AuthControllerIntegrationTest.java index b7b6078..f56ec22 100644 --- a/src/test/java/org/nkcoder/controller/AuthControllerSecurityTest.java +++ b/src/test/java/org/nkcoder/integration/AuthControllerIntegrationTest.java @@ -1,4 +1,4 @@ -package org.nkcoder.controller; +package org.nkcoder.integration; import static org.mockito.ArgumentMatchers.any; import static org.mockito.BDDMockito.given; @@ -12,6 +12,7 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; +import org.nkcoder.config.IntegrationTest; import org.nkcoder.dto.auth.AuthResponse; import org.nkcoder.dto.auth.AuthTokens; import org.nkcoder.dto.user.UserResponse; @@ -21,43 +22,18 @@ import org.nkcoder.util.JwtUtil; import org.springframework.beans.factory.annotation.Autowired; 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.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; /** * Use @SpringBootTest to load the full context to test the authentication of endpoints. * Because @WebMvcTest won't load SecurityConfig and JwtAuthenticationEntryPoint. */ -@SpringBootTest @AutoConfigureMockMvc +@IntegrationTest @DisplayName("AuthController Security Tests") -@ActiveProfiles("test") -public class AuthControllerSecurityTest { - - // Singleton container for database (needed by JPA) - static PostgreSQLContainer postgres; - - static { - postgres = - new PostgreSQLContainer<>("postgres:17") - .withDatabaseName("testdb") - .withUsername("test") - .withPassword("test"); - postgres.start(); - } - - @DynamicPropertySource - static void configureProperties(DynamicPropertyRegistry registry) { - registry.add("spring.datasource.url", postgres::getJdbcUrl); - registry.add("spring.datasource.username", postgres::getUsername); - registry.add("spring.datasource.password", postgres::getPassword); - } +public class AuthControllerIntegrationTest { @Autowired private MockMvc mockMvc;