Spring @Sql, 테스트 데이터 설정

개발을 하다 보면 테스트를 위한 데이터 셋팅이 너무 귀찮고 힘들고 특히 테이블 연관관계가 복잡하게 얽혀 있을 때는, 단순히 한 두 개의 엔티티를 만드는 것이 아니라 관련된 모든 엔티티를 하나씩 만들어줘야 하는, 귀찮음이 몰려옵니다

User를 만든다 → 연관된 Town이 필수

Character를 만든다 → Product가 필수

UserCharacter 만든다 → User, character를 넣어야한다.

결국, 유저와 유저 캐릭터만 필요해도 실제로는 5개 이상의 엔티티를 만들어줘야 상황

1. 직접 값 세팅

초기에는 테스트를 위해 직접 엔티티들을 생성하고, EntityManager를 사용하여 직접 persist하는 방식으로 데이터를 세팅했습니다.

사실 이전엔 각각 Repository를 불러와 Save했었는데 전부 Autowired필요해 기본 코드만 수십줄..

실제로 아래와 같은 코드를 작성

@SpringBootTest
@Transactional
class BookReportQueryRepositoryImplTest {

	@Autowired
	private BookReportRepository bookReportRepository;

	@Autowired
	private EntityManager em;

	private School school;
	private ClassRoom classRoom;
	private User teacher;
	private User student;
	private StudentClass studentClass;
	private TeacherClass teacherClass;
	private Book book;
	private BookReport bookReport;

	@BeforeEach
	void setUp() {
		school = SchoolSample.school();
		em.persist(school);

		classRoom = ClassRoomSample.classRoom(school);
		em.persist(classRoom);

		student = UserSample.user(학생);
		teacher = UserSample.user(교사);
		em.persist(student);
		em.persist(teacher);

		studentClass = StudentClassSample.studentClass(student, classRoom);
		teacherClass = TeacherClassSample.teacherClass(teacher, classRoom);
		em.persist(studentClass);
		em.persist(teacherClass);

		book = BookSample.book("테스트제목");
		em.persist(book);

		bookReport = BookReportSample.bookReport(studentClass, book);
		em.persist(bookReport);

		em.flush();
		em.clear();
	}
}

이렇게 직접 엔티티를 생성하고 persist하는 과정은 너무 힘들고 매번 반복 발생

2. 헬퍼(Helper) 클래스 도입

그래서 어느 순간 테스트 데이터 생성을 도와줄 TestEntityHelper라는 클래스를 만들었습니다.

이 헬퍼를 사용하면, 다음과 같이 훨씬 간편하게 테스트 데이터를 생성할 수 있습니다.

@SpringBootTest
@Transactional
public class UserCharacterServiceTest {

	@Autowired
	private UserCharacterService userCharacterService;

	@Autowired
	private TestEntityHelper helper;
	@Autowired
	private UserCharacterRepository userCharacterRepository;

	private Town town;
	private User user;
	private Product product1;
	private Product product2;
	private Character character1;
	private Character character2;
	private UserCharacter userCharacter1;
	private UserCharacter userCharacter2;

	@BeforeEach
	void setUp() {
		town = helper.createTown();
		user = helper.createUser(town);

		product1 = helper.createProduct();
		product2 = helper.createProduct();

		character1 = helper.createCharacter(product1);
		character2 = helper.createCharacter(product2);

		userCharacter1 = helper.createUserCharacter(user, character1);
		userCharacter2 = helper.createUserCharacter(user, character2);
	}
}

헬퍼 덕분에 코드는 깔끔해졌지만, 여전히 서비스마다 테스트를 위해 이런 초기화 코드를 작성해야 하는 번거로움은 남았습니다.

3. @Sql 스크립트로 테스트 데이터 초기 삽입

이대로 테스트때문에 고통받을 수 없다라는 생각으로 열심히 구글링한 결과