TTD를 작성하다보면 local과는 관계 없이 실행할 수 있어야한다. 따라서 local과 test용으로 따로 분리를 해줘야한다.
파일 구조
application.properties (기본 설정 파일)application-local.properties (로컬용 설정 파일)application-test.properties (테스트용 설정 파일)
application.properties(기본 설정 파일)
spring.profiles.active=local
# JWT
jwt.secret=uz7MtIBd5PpX0knZuSB4RLlgFJ/v7ySsMofaMGZ1wec=
jwt.expiration-time=43200000
# JPA
spring.jpa.properties.hibernate.show_sql=true
spring.jpa.properties.hibernate.use_sql_comment=true
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.properties.hibernate.highlight_sql=true
logging.level.org.hibernate.orm.jdbc.bind=TRACE
spring.profiles.active=local이게 꼭 들어가서 기본 설정이 local과 같다는 것을 넣어줘야한다.
application-local.properties(로컬용 설정 파일)
spring.datasource.url=jdbc:postgresql://localhost:5432/db이름
spring.datasource.username=이름
spring.datasource.password=이름
spring.datasource.driver-class-name=org.postgresql.Driver
spring.jpa.hibernate.ddl-auto=create
postSql을 사용할 때 db를 만드는 부분을 넣어준다.
application-test.properties(테스트용 설정 파일)
빈 파일로 만들어둔다.
테스트를 위해 @ActiveProfiles("test") 을 넣어줘야한다.
import org.springframework.test.context.ActiveProfiles;
@ActiveProfiles("test") // application-test.properties 설정 적용
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class StudentAcceptanceTest {
// 생략
}
테스트끼리의 영향을 받지 않기 위한 격리도 필요하다.
test에 DataBaseCleanUP의 파일을 만들어둔다.
import jakarta.persistence.Entity;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.stream.Collectors;
@Service
public class DatabaseCleanup implements InitializingBean {
@PersistenceContext
private EntityManager entityManager;
private List<String> tableNames;
@Override
public void afterPropertiesSet() {
tableNames = entityManager.getMetamodel().getEntities().stream()
.filter(e -> e.getJavaType().getAnnotation(Entity.class) != null)
.map(e -> e.getName()
.replaceAll("([a-z])([A-Z])", "$1_$2") // camel case to snake case
.toLowerCase())
.collect(Collectors.toList());
}
@Transactional
public void execute() {
entityManager.flush();
entityManager.createNativeQuery("SET REFERENTIAL_INTEGRITY FALSE").executeUpdate();
for (String tableName : tableNames) {
entityManager.createNativeQuery("TRUNCATE TABLE " + tableName).executeUpdate();
entityManager.createNativeQuery("ALTER TABLE " + tableName + " ALTER COLUMN ID RESTART WITH 1").executeUpdate();
}
entityManager.createNativeQuery("SET REFERENTIAL_INTEGRITY TRUE").executeUpdate();
}
}
이 만들어둔 파일을 test할 때 주입해주면 된다.
@Autowired
DatabaseCleanup databaseCleanup;
@BeforeEach
void setUp() {
databaseCleanup.execute();
}
이런식으로 작성해준다.