Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

테스트 시 DB 격리 및 레포지토리 테스트를 위한 베이스 어노테이션 생성 #529

Merged
merged 3 commits into from
Aug 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions backend/src/test/java/codezap/global/DatabaseCleaner.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package codezap.global;

import java.util.List;

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.TestContext;
import org.springframework.test.context.support.AbstractTestExecutionListener;

public class DatabaseCleaner extends AbstractTestExecutionListener {

@Override
public void beforeTestMethod(TestContext testContext) {
JdbcTemplate jdbcTemplate = testContext.getApplicationContext().getBean(JdbcTemplate.class);
List<String> queries = getTruncateQueries(jdbcTemplate);
truncate(queries, jdbcTemplate);
}

private List<String> getTruncateQueries(final JdbcTemplate jdbcTemplate) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
private List<String> getTruncateQueries(final JdbcTemplate jdbcTemplate) {
private List<String> getTruncateQueries(JdbcTemplate jdbcTemplate) {

return jdbcTemplate.queryForList(
"SELECT CONCAT('TRUNCATE TABLE ', TABLE_NAME, ';') " +
"FROM INFORMATION_SCHEMA.TABLES " +
"WHERE TABLE_SCHEMA = DATABASE();",
String.class
);
}

private void truncate(List<String> queries, JdbcTemplate jdbcTemplate) {
jdbcTemplate.execute("SET FOREIGN_KEY_CHECKS = 0;");
queries.forEach(jdbcTemplate::execute);
jdbcTemplate.execute("SET FOREIGN_KEY_CHECKS = 1;");
}
}
11 changes: 11 additions & 0 deletions backend/src/test/java/codezap/global/DatabaseIsolation.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package codezap.global;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

import org.springframework.test.context.TestExecutionListeners;

@Retention(RetentionPolicy.RUNTIME)
@TestExecutionListeners(value = DatabaseCleaner.class, mergeMode = TestExecutionListeners.MergeMode.MERGE_WITH_DEFAULTS)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 부분은 우리가 만든 DatabaseCleaner 클래스를 테스트 실행 리스너로 등록한다는 의미입니다.

mergeModes의 MERGE_WITH_DEFAULTS는 우리가 추가한 DatabaseCleaner를 기존 스프링의 기본 리스너들과 함께 사용하겠다는 의미입니다.
(이 모드를 사용하지 않으면, 기본 스프링의 리스너들이 모두 무시되고 DatabaseCleaner만 사용되게 됩니다.)

public @interface DatabaseIsolation {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package codezap.global.repository;

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.test.context.ActiveProfiles;

import codezap.global.DatabaseIsolation;
import codezap.global.auditing.JpaAuditingConfiguration;

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@DataJpaTest
@DatabaseIsolation
@Import(JpaAuditingConfiguration.class)
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
Copy link
Contributor Author

@jminkkk jminkkk Aug 21, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

코드가 낯설까봐 추가 코멘트 달아요 🔥
이해 안되시는 부분 있다면 말해주세요 ⚡️


@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) 는 테스트용 인메모리 데이터베이스가 아닌 실제 설정된 데이터베이스를 사용하도록 합니다.

@DataJpaTest이 실행될 때 스프링은 기본적으로 테스트 시 인메모리 데이터베이스 (기존 h2를 사용했을 때처럼 우리 컴퓨터의 메모리에 데이터를 저장하는 DB)로 테스트를 실행 시킵니다.

따라서 우리 테스트 환경인 mysql로 테스트 데이터베이스를 사용하려면 해당 어노테이션을 달아줘야 합니당

public @interface JpaRepositoryTest {
}