Spring boot CommandLineRunner로 테스트 데이터 초기화

koonlx·2024년 8월 16일

stay_connect

목록 보기
3/10

1. 테스트 데이터를 초기화하는 방법들

  • CommandLineRunner
  • ApplicationRunner
  • @PostConstruct
  • @EventListener

2. CommandLineRunner를 선택한 이유

  • 간단함과 명확성: CommandLineRunner는 구현이 간단하며, 코드의 의도가 명확하다. 애플리케이션 시작 시 실행해야 하는 초기화 작업이 있을 때 가장 직관적이다.
  • Spring 컨텍스트와의 통합: Spring 컨텍스트가 완전히 초기화된 후 실행되기 때문에, 데이터베이스 연결이나 필요한 빈들이 모두 준비된 상태에서 작업을 수행할 수 있다. 이는 의존성 주입이 완료된 후에 실행해야 하는 초기화 작업에 매우 유리하다.
  • 다양한 환경에 쉽게 적용 가능: CommandLineRunner는 개발, 테스트, 프로덕션 등 여러 환경에서 동일한 방식으로 사용할 수 있다. 필요한 경우 환경에 따라 조건부로 실행될 로직을 추가할 수도 있다.

3. 다른 대안들과 비교

  • ApplicationRunner: CommandLineRunner와 동일한 기능과 성능에 추가적으로 명령줄 인자를 처리할 수 있다. 하지만 지금 나에겐 필요하지 않기 때문에 CommandLineRunner를 선택했다.
  • @PostConstruct: 빈 초기화 시점을 제어할 수 없기 때문에, 의존성이 모두 주입되기 전에 실행될 수 있는 위험이 있다. 이는 데이터베이스 초기화와 같은 작업에는 적합하지 않다.
  • @EventListener(ApplicationReadyEvent.class): 애플리케이션이 완전히 준비된 후 실행되지만, 복잡한 초기화 로직이 필요한 경우가 아니면 과도한 설정일 수 있다.

4. 코드 작성

@Order(3) // CommandLineRunner의 실행 순서 지정.
@Component // Spring Component Scan으로 Bean 등록.
public class UserInitializer implements CommandLineRunner {

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private RoleRepository roleRepository;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    public void run(String... args) throws Exception {
        final int TOTAL_USERS = 10;
        final String ADMIN_USERNAME = "admin";
        final String ADMIN_PASSWORD = "admin";
        final String ADMIN_REAL_NAME = "Admin";
        final String ADMIN_PHONE_NUMBER = "010-1234-5678";
        final String ADMIN_EMAIL = "admin@example.com";
        final String USER_PASSWORD_PREFIX = "user";
        final String USER_EMAIL_PREFIX = "example.com";
        final LocalDate USER_BIRTH_DATE = LocalDate.of(1995, 1, 1);

        // Role 가져오기 또는 생성
        Role adminRole = roleRepository.findByName("ROLE_ADMIN").orElseGet(() -> createRole("ROLE_ADMIN"));
        Role userRole = roleRepository.findByName("ROLE_USER").orElseGet(() -> createRole("ROLE_USER"));

        // 사용자 생성
        for (int i = 0; i < TOTAL_USERS; i++) {
            User user = (i == 0)
                    ? createUser(ADMIN_USERNAME, ADMIN_PASSWORD, ADMIN_REAL_NAME, LocalDate.of(1990, 1, 1), true,
                            ADMIN_PHONE_NUMBER, ADMIN_EMAIL, adminRole)
                    : createUser(USER_PASSWORD_PREFIX + i, USER_PASSWORD_PREFIX + i, "User " + i, USER_BIRTH_DATE, true,
                            "010-1234-567" + i, "user" + i + "@" + USER_EMAIL_PREFIX, userRole);
            userRepository.save(user);
        }
    }

    private Role createRole(String roleName) {
        Role role = new Role();
        role.setName(roleName);
        return roleRepository.save(role);
    }

    private User createUser(String username, String password, String realName, LocalDate birth, boolean gender,
            String phoneNumber, String email, Role role) {
        return User.builder()
                .username(username)
                .password(passwordEncoder.encode(password))
                .realName(realName)
                .birth(birth)
                .gender(gender)
                .phoneNumber(phoneNumber)
                .email(email)
                .role(role)
                .build();
    }
}

이런식으로 필요한만큼 Spring boot가 실행된 후 실행할 코드들을 작성하여 사용하면 된다. 손쉽게 테스트 데이터를 준비할 수 있다.

profile
Server Developer

0개의 댓글