JUnit5 - Nested, Tags, Interface, DI, Repeat

Tag

테스트 클래스에 @Tag 어노테이션을 추가해주는 것 만으로는 아무런 차이가 없습니다. JUnit configuration에서 JUnit 테스트를 만들 때, Test Kind 의 설정 값을 Tags로 설정해줍니다. Tag expression 의 값으로는 @Tag 어노테이션의 value 값을 입력해줍니다.

Nested

@Nested 테스트는 테스트 작성자가 테스트하는 그룹들 간의 관계를 표현하는데 더 유용한 기능을 제공합니다. 오직 static하지 않은 클래스들만 @Nested 테스트 클래스로 제공될 수 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
@DisplayName("Owner Map Service Test - ")
class OwnerMapServiceTest {

OwnerMapService ownerMapService;
PetTypeService petTypeService;
PetService petService;

@BeforeEach
void setUp() {
petTypeService = new PetTypeMapService();
petService = new PetMapService();
ownerMapService = new OwnerMapService(petTypeService, petService);
}

@DisplayName("Verify Zero Owners")
@Test
void ownersAreZero() {
int ownerCount = ownerMapService.findAll().size();

assertThat(ownerCount).isZero();
}

@DisplayName("Pet Type - ")
@Nested
class TestCreatePetTypes {

@BeforeEach
void setUp() {
PetType petType = new PetType(1L, "Dog");
PetType petType2 = new PetType(2L, "Cat");
petTypeService.save(petType);
petTypeService.save(petType2);
}

@DisplayName("Test Pet Count")
@Test
void testPetCount() {
int petTypeCount = petTypeService.findAll().size();

assertThat(petTypeCount).isNotZero().isEqualTo(2);
}

@DisplayName("Save Owners Tests - ")
@Nested
class SaveOwnersTests {

@BeforeEach
void setUp() {
ownerMapService.save(new Owner(1L, "Before", "Each"));
}

@DisplayName("Save Owner")
@Test
void saveOwner() {
Owner owner = new Owner(2L, "Joe", "Buck");

Owner savedOwner = ownerMapService.save(owner);

assertThat(savedOwner).isNotNull();
}

@DisplayName("Save Owners Tests - ")
@Nested
class FindOwnersTests {

@DisplayName("Find Owner")
@Test
void findOwner() {

Owner foundOwner = ownerMapService.findById(1L);

assertThat(foundOwner).isNotNull();
}

@DisplayName("Find Owner Not Found")
@Test
void findOwnerNotFound() {

Owner foundOwner = ownerMapService.findById(2L);

assertThat(foundOwner).isNull();
}
}
}
}

@DisplayName("Verify Still Zero Owners")
@Test
void ownersAreStillZero() {
int ownerCount = ownerMapService.findAll().size();

assertThat(ownerCount).isZero();
}
}

테스트 클래스 안에 테스트 클래스를 만들 수 있습니다. 상위 테스트에서 생성된 컨텍스트를 공유받을 수 있습니다. 라이프 사이클에 의해서 상위에서는 다른 하위 테스트의 컨텍스트를 공유받을 수 없습니다.

Test Interfaces

테스트 클래스들은 인터페이스를 구현할 수 있습니다. JUnit4에서는 테스트 클래스는 인터페이스를 구현 할 수 없었습니다.

Default test method

Java8 부터는 인터페이스의 디폴트 메소드를 구현할 수 있습니다. 테스트에서도 디폴트 메소드등을 정의하여 사용할 수 있습니다. 테스트 별로 공통적으로 동작하는 BeforeAll, AfterAll 과 같은 동작들을 정의 해줄 수 있습니다. 이때, BeforeAll의 경우 static한 클래스에서는 사용할 수 없기 때문에 @TestInstance 의 값을 지정해줍니다.

1
2
3
4
5
6
7
8
9
@Tag("repeated")
public interface ModelRepeatedTests {

@BeforeEach
default void beforeEachConsoleOutputer(TestInfo testInfo, RepetitionInfo repetitionInfo){
System.out.println("Running Test - " + testInfo.getDisplayName() + " - "
+ repetitionInfo.getCurrentRepetition() + " | " + repetitionInfo.getTotalRepetitions());
}
}

RepeatedTest

테스트를 몇 번 반복해서 수행할 것인지 지정할 수 있습니다. 속성값들이 있으니 확인하고 사용하면 결과 볼때 도움을 받을 수 있습니다.

1
2
3
4
@RepeatedTest(value = 10, name = "{displayName} : {currentRepetition} - {totalRepetitions}")
@DisplayName("My Repeated Test")
void myRepeatedTest() {
}

Parameter Resolver

JUnit5는 런타임에 파라미터를 리졸브하기 위해서 Parameter Resulver API를 제공합니다. 이를 통해서 JUnit이 테스트 메소드에 파라미터를 주입하는 것을 허용합니다. TestInfo, RepetitionInfo, TestReporter 를 제공합니다.

  • TestInfo
    • 테스트의 이름, 메소드, 클래스, 태그에 대한 정보를 제공
  • RepetitionInfo
    • 테스트의 반복에 대한 정보를 제공
  • TestReporter
    • 테스트 결과를 리포팅하기 위해서 런타임 정보를 발행하는 것을 허용

Test Dependency Injection

테스트의 런타임 동안 의존성 주입을 통해서 테스트에 대한 정보를 제공받을 수 있습니다.

1
2
3
4
5
@RepeatedTest(5)
void myRepeatedTestWithDI(TestInfo testInfo, RepetitionInfo repetitionInfo) {
System.out.println(testInfo.getDisplayName() + ": " + repetitionInfo.getCurrentRepetition());

}
JUnit5 - parameterized JUnit5 - assertAll 외

Comments

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×