๊ธฐ์กด์ ์๋น์ค ์ฝ๋
@DataJpaTest
@Import(ReservationConfig.class)
class ReservationApplicationServiceTest {
// ... ํ์ํ ์ฃผ์
๋ฐ ํ
์คํธ ...
static class ReservationConfig {
// @Bean
// ... ํ์ํ ์ค์ ๊ฐ์ฒด ์ฃผ์
...
}
}
๋ฌธ์ ์
1. @DataJpaTest๋ฅผ ์ฌ์ฉํ๊ณ ์๋ค.
์ผ๋ฐ์ ์ผ๋ก @DataJpaTest ๋ ์ผ๋ฐ์ ์ผ๋ก Repository ํ ์คํธ๋ฅผ ์ํ ๊ฒ์ด๋ค! ๊ฒ๋ค๊ฐ Service ํ ์คํธ์์ ์กฐ์ฌํ๊ฒ ์ฌ์ฉํด์ผ ํ๋ @Transactional ์ ๋ ธํ ์ด์ ์ด ๊ธฐ๋ณธ์ ์ผ๋ก ๋ถ์ด์๋ค. ๊ทธ๋ ๊ธฐ์ ๋ค๋ฅธ ๋ฐฉ๋ฒ์ ์ฐพ์์ผ ํ๋ค.
2. inner class๋ก ReservationConfig๋ฅผ ํตํด ๋น์ ์ง์ ๋ฑ๋กํ๊ณ ์๋ค.

์ด๋ ๊ฒ๊น์ง ๋น์ ๋ฑ๋กํ๋ฉฐ ์๋น์ค๋ฅผ ํ ์คํธ ํ๋ ๊ฒ์ ์์น ์๋๋ค.
๊ฐ์ ํด๋ณด์.
๋จผ์ @DataJpaTest ์ ๋ ธํ ์ด์ ์ ์ ๊ฑฐํด๋ณด์.
์คํ๋ง์๋ @WebMvcTest, @EnableJpaRepositories ๋ฑ… ๋ง์ ์ ๋ ธํ ์ด์ ์ด ์๋ค. ํ์ง๋ง, ์๋น์ค ํ ์คํธ๋ฅผ ์ํด์๋ Jpa ๊ด๋ จ ๋น๊ณผ Service, Repository ๊ตฌํ์ฒด์ ๋ํ ๋น๋ค๋ ํ์ํ๋ค. ์์ ์ ๋ ธํ ์ด์ ๋ค์ ํ์ฉํ๋ค๊ณ ํด๋ ๋จํธ์ ์ผ๋ก ๋น์ ๋ฑ๋กํ๋ค. ๊ทธ๋์ ๊ฒฐ๊ตญ ์ด์ ์ฒ๋ผ ๋น์ ๋ฑ๋กํด์ฃผ๋ Config inner class๋ฅผ ๋ง๋ค์ด์ผ ํ๋ค. ๊ทธ๋ฌ๋ฉด ์คํ๋ง ์ปจํ ์คํธ๋ฅผ ๋ง๋ค๊ณ ์ ์ฒด์ ์ผ๋ก ๋น์ ๋ง๋ค์ด์ฃผ๋ ์ ๋ ธํ ์ด์ ์ ํ์ฉํ ์ ๋ฐ์ ์์ง ์์๊น? ๊ทธ ์ญํ ์ ํ๋ ์ ๋ ธํ ์ด์ ์ด ๋ฐ๋ก @SpringBootTest ์ด๋ค.
ํ์ง๋ง @SpringBootTest ๋ฅผ ๊ทธ๋๋ก ์ฌ์ฉํ๊ธฐ์ ๋๋ฌด๋๋ ๋๋ฆฌ๋ค. ๊ทธ๋ฆฌ๊ณ ์๋น์ค ๊ณ์ธต์ ๋์ด ์ปจํธ๋กค๋ฌ์ ๊ธฐํ ์น ๊ด๋ จ ๋น๋ค๋ ์์ฑํ๊ธฐ์ ํตํฉ ํ ์คํธ์์๋ ํ์ฉํ ์ ์์ง, ์๋น์ค์ ๋จ์ ํ ์คํธ์๋ ์ ํฉํ์ง ์๋ค. ๊ทธ๋์ ์ด๋ฅผ ์ด๋์ ๋ ์ ํํ๋ ์ต์ ์ ํ์ฉํ๋ค.
๋ฐ๋ก webEnvironment = SpringBootTest.WebEnvironment.NONE ์ด๋ค. ์ด ์ต์ ์ ๋ฃ์ผ๋ฉด ์ด์ ์ฒ๋ผ ์คํ๋ง ์ปจํ ์คํธ๋ฅผ ๋ง๋ค๊ณ ๋น๋ค์ ์์ฑํ์ง๋ง ๊ทธ ์ด์์ ์น ์์ฒญ/์๋ต ํ๋ฆ์ ๊ด๋ จ ๋น๋ค์ ์์ฑํ์ง ์๋๋ค. ์ฆ, ๋์คํจ์ฒ ์๋ธ๋ฆฟ, ๋ฆฌ์กธ๋ฒ, ํธ๋ค๋ฌ ๋ฑ์ ๋น์ด ์์ฑ๋์ง ์๋๋ค! ์๋น์ค ํ ์คํธ์ ์ ํฉํ ๊ฒ ๊ฐ๋ค. ์ฝ๋๋ก ํํํ๋ค๋ฉด ๋ค์์ฒ๋ผ ๋ ๊ฒ์ด๋ค.
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
class ReservationApplicationServiceTest {
// ... ํ์ํ ์ฃผ์
๋ฐ ํ
์คํธ ...
}
์ด๋ก์จ ๋ฌธ์ ์ 1๋ฒ๊ณผ 2๋ฒ์ ๋ชจ๋ ํด๊ฒฐํ๋ค. ํ์ง๋ง, ๊ฐ๊ณผํ ๊ฒ์ด ํ๋ ์๋ค. ๋ฐ๋ก ๊ณต์ ์์กด์ฑ์ด๋ค.
๊ณต์ ์์กด์ฑ์ ํ ์คํธ ๊ฐ์ ์๋ก ๊ณต์ ๋๋ ์์กด์ฑ์ผ๋ก ํ๋์ ํ ์คํธ์์ ์ํํ ๊ฒฐ๊ณผ๊ฐ ๋ค๋ฅธ ํ ์คํธ์๋ ์ํฅ์ ๋ฏธ์น๋ ๊ฒ์ด๋ค. ๋ํ์ ์ผ๋ก ๋ฐ์ดํฐ๋ฒ ์ด์ค๊ฐ ์๋ค. @DataJpaTest๋ฅผ ์ฌ์ฉํ์ ๋๋ ๋ด๋ถ์ @Transactional์ด ์์๊ธฐ ๋๋ฌธ์ ํ ์คํธ๋ง๋ค ๋กค๋ฐฑ๋์ด DB๊ฐ ๊ณต์ ์์กด์ฑ์ด ์๋๊ฒ ๋์์ง๋ง ์ง๊ธ์ ํด๊ฒฐ๋ฐฉ์์ ๋ด๋ถ์ ์ผ๋ก๋ ์ธ๋ถ์ ์ผ๋ก @Transactional์ด ์์ด์ ๊ณต์ ์์กด์ฑ์ด ๋์๋ค.
๊ทธ๋ ๋ค๊ณ ์๋น์ค ํ ์คํธ์ @Transactional์ ๋ถ์ด๋ ๊ฒ์ ์ํํ๋ค. ์๋๋ฉด, ์๋น์ค ๋ก์ง ์ ํธ๋์ญ์ ์ ์๋ํ์ง ์์์์๋ ํ ์คํธ์๋ ํธ๋์ญ์ ์ด ๋ถ๊ธฐ ๋๋ฌธ์ ํ ์คํธ๊ฐ ๊ฑฐ์ง ์์ฑ์ด ๋ ํ๋ฅ ์ด ๋์์ง๊ธฐ ๋๋ฌธ์ด๋ค. ๊ทธ๋ ๋ค๋ฉด ์ฌ์ค ๋ฐฉ๋ฒ์ ํ๋ ๋ฟ์ด๋ค. ๋ฐ๋ก ์ง์ DB๋ฅผ ๋กค๋ฐฑํ๋ ๊ฒ!!
@SpringBootTest(webEnvironment = WebEnvironment.NONE)
public abstract class BaseServiceTest {
@Autowired
private DatabaseCleaner databaseCleaner;
@BeforeEach
void setUp() {
databaseCleaner.clean();
}
}
@Component
public class DatabaseCleaner {
private static final String FOREIGN_KEY_SET_ON = "SET REFERENTIAL_INTEGRITY TRUE";
private static final String FOREIGN_KEY_SET_OFF = "SET REFERENTIAL_INTEGRITY FALSE";
private static final String TRUNCATE_TABLE_QUERY = "TRUNCATE TABLE %s RESTART IDENTITY";
@PersistenceContext
private EntityManager entityManager;
private List<String> tableNames;
@PostConstruct
void setTableNames() {
tableNames = entityManager.getMetamodel().getEntities().stream()
.filter(entityType -> entityType.getJavaType().getAnnotation(Entity.class) != null)
.map(entityType -> CaseFormat.convertCamelToSnake(entityType.getName()).toLowerCase())
.filter(tableName -> !(tableName.equals("member") || tableName.equals("admin")))
.toList();
}
@Transactional
void clean() {
entityManager.createNativeQuery(FOREIGN_KEY_SET_OFF).executeUpdate();
for (String tableName : tableNames) {
entityManager.createNativeQuery(String.format(TRUNCATE_TABLE_QUERY, tableName)).executeUpdate();
}
entityManager.createNativeQuery(FOREIGN_KEY_SET_ON).executeUpdate();
entityManager.flush();
entityManager.clear();
}
}
๊ฒฐ๊ณผ๋ถํฐ ๋ณด์๋ฉด ๋๋ ์ด๋ ๊ฒ ํ ์คํธ ์ฝ๋๋ฅผ ๊ฐ์ ํ๋ค. ๋ชจ๋ ์๋น์ค ํ ์คํธ๊ฐ ํ ์คํธ ๋ฉ์๋๊ฐ ์์ํ๊ธฐ ์ @BeforeEach๋ก DB๋ฅผ ๋กค๋ฐฑ์ํฌํ ๊ณ , @SpringBootTest(webEnvironment = WebEnvironment.NONE) ์ ๋ ธํ ์ด์ ์ด ๋ถ์ํ ๋๊น ์ด๋ฅผ ํ๋์ ํด๋์ค๋ก ๋ฌถ์ด์คฌ๋ค. ๊ทธ๋ฆฌ๊ณ , ์๋น์ค ํ ์คํธ๊ฐ ์ด๋ฅผ ์์ํ๋ ๋ฐฉ๋ฒ์ผ๋ก ๊ตฌํํ๋ค.
์ด๋ก์จ ์๋น์ค ํ ์คํธ๋ BaseServiceTest๋ง ์์ ๋ฐ์ผ๋ฉด ์ง์ ๋ถํ Config ํ์ผ์ด ํ์์๋ค๋ ์ ๊ณผ @DataJpaTest ์ ๋ ธํ ์ด์ ์ ๊ฑฐ๋ฅผ ์ด๋ค๋ผ ์ ์๋ค.


์์ฝ๊ฒ๋ ์๊ฐ ์์ฒด๋ ์ข ๋์ด๋ฌ์ง๋ง, ์๋น์ค ํ ์คํธ๋ผ๋ ๋ชฉ์ ์ฑ์ ๋ฌ์ฑํ ์ ์์์ผ๋ ์๋ฏธ์๋ ๊ฐ์ ์ด๋ผ๊ณ ์๊ฐํ๋ค.
'๊ฐ๋ฐ > ์ฐ์ํํ ํฌ์ฝ์ค' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| ์ฐํ ์ฝ ๋ ๋ฒจ 2 ํ๊ณ (4) | 2025.06.13 |
|---|---|
| ์ฐํ ์ฝ ๋ ๋ฒจ 2์์์ ์ธ ๋ฒ์งธ ๋ฏธ์ ํ๊ณ (17) | 2025.06.01 |
| ์์์ฑ ์ปจํ ์คํธ (1) | 2025.05.19 |
| ์ฐํ ์ฝ ๋ ๋ฒจ 2์ ๋ฏธ์ 2 ํ๊ณ (4) | 2025.05.19 |
| persist๋ฅผ ํ๋ฉด ์์์ฑ ์ปจํ ์คํธ์์ ์ผ์ด๋๋ ์ผ (1) | 2025.05.16 |