배경
- 단위 테스트를 진행하던 도중 초기값을 구성하려고 하는데,
- 아래와 같이 실행했더니 두 번째로 실행된 테스트에서 20개의 사이즈를 가진 List가 아니었다.
private final List<StudyTag> tags = new ArrayList<>();
@BeforeEach
void setUp() {
for (int i = 0; i < 10; i++) {
StudyTag tag = Mockito.mock(StudyTag.class);
Mockito.when(tag.getId()).thenReturn(Long.valueOf(i));
tags.add(tag);
}
}
@Test
@DisplayName("validateAllIdsPresent 성공한다.")
void validateAllIdsPresent_Success() {
//when & then
for (StudyTag tag : tags) {
System.out.println(tag);
}
}
@Test
@DisplayName("validateAllIdsPresent 실패한다.")
void validateAllIdsPresent_ThenFail() {
for (StudyTag tag : tags) {
System.out.println(tag);
}
}
TestInstance
- JUnit 5는 기본값으로 TestInstance.Lifecycle.PER_METHOD를 사용한다.
- PER_METHOD 모드에서는 테스트 메소드마다 테스트 클래스의 인스턴스를 새로 생성한다.
- 따라서 각 테스트 메서드마다 아래와 같이 동작한다.
- 테스트 클래스 인스턴스 생성
- 필드 초기화
- 생명주기 메소드 실행
- 테스트 메소드 실행
- 인스턴스 파기
- 이와 같은 이유로 @BeforeAll, @AfterAll에서 static 키워드가 붙어야 하는 이유이다. <- TestInstance.Lifecycle을 PER_CLASS로 하면 static을 안 붙여줘도 된다.
결론
- TestInstance의 Lifecycle이 PER_METHOD이기에 새로 인스턴스를 만들고, 필드를 초기화하기 때문에 발생한 일이다.
- 이와 반대로 PER_CLASS로 지정할 시엔 tags의 사이즈가 20개 되는 것을 볼 수 있다.