JUnit5 @ParameterizedTest
테스트 코드를 작성하던 중, 한 기능에서 로직은 같지만 입력 파라미터만 다른 테스트케이스를 작성해야 할 일이 있었다. 코드는 중복되지만, 각 케이스에 대한 검증은 필요하므로 테스트 코드를 작성하지 않을 수는 없다.
이러한 경우 조금 더 코드를 간결하게 작성하는 방법이 있지 않을까 고민해보고 찾아보는 중 Junit5에서 제공하는 @ParameterizedTest
라는 것을 알게 되었다.
@ParameterizedTest
@ParameterizedTest는 하나의 테스트를 여러 번 돌려야 할 때 사용한다.
@ParameterizedTest 적용 방법
- 메소드 위에
@ParameterizedTest
를 명시한다. - 메소드의 파라미터로 순서대로 넘겨줄 배열을
@ValueSource
를 이용해 명시해준다. (short, byte, int, long, float, double, char, String, Class 명시 가능) - 넘겨줄 값들의 타입을 메소드의 파라미터로 적어준다.
예시
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.mockito.junit.jupiter.MockitoExtension;
@ExtendWith(MockitoExtension.class)
public class TestControllerTest {
@ParameterizedTest
@ValueSource(strings = {"test1", "test2", "test3"})
void test(String value) {
System.out.println(value);
}
}
이 테스트 코드의 실행 결과는 다음과 같다.
하지만, 이 방법은 파라미터를 하나만 전달할 때만 가능하며 두 개 이상의 파라미터는 전달할 수 없다.
@MethodSource
@MethodSource
를 이용하면 두 개 이상의 파라미터 또한 전달받을 수 있도록 할 수 있다.
예시
import java.util.stream.Stream;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import org.mockito.junit.jupiter.MockitoExtension;
@ExtendWith(MockitoExtension.class)
public class TestControllerTest {
// test method
@ParameterizedTest
@MethodSource("provideKeyAndValue")
void test(Integer key, String value) {
System.out.println(key + " " + value);
}
//source method
private static Stream<Arguments> provideKeyAndValue() {
return Stream.of(
Arguments.of(1, "value1"),
Arguments.of(2, "value2"),
Arguments.of(3, "value3")
);
}
}
단, 이를 사용하기 위해서는 source method가 static이어야 한다.
하지만, 성격이 같은 테스트케이스끼리 묶을 경우 종종 inner class를 사용하는 경우가 있고, inner class에서는 static method를 선언하지 못한다.
import java.util.stream.Stream;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import org.mockito.junit.jupiter.MockitoExtension;
@ExtendWith(MockitoExtension.class)
public class TestControllerTest {
@Nested
public class NestedTestControllerTest {
@ParameterizedTest
@MethodSource("provideKeyAndValue")
public void test(Integer key, String value) {
System.out.println(key + " " + value);
}
// 에러 발생!
private static Stream<Arguments> provideKeyAndValue() {
return Stream.of(
Arguments.of(1, "value1"),
Arguments.of(2, "value2"),
Arguments.of(3, "value3")
);
}
}
}
이렇게 불가능하다는 뜻이다... 이럴 때는 @TestInstance
를 사용하면 되는데, 이제부터 @TestInstance
에 대해 알아볼 예정이다.
@TestInstance
@TestInstance는 테스트 인스턴스의 라이프 사이클을 설정할 때 사용한다.
- Lifecycle.PER_METHOD (Default) : 테스트 함수 당 인스턴스가 생성된다.
- Lifecycle.PER_CLASS : 테스트 클래스 당 인스턴스가 생성된다.
import java.util.stream.Stream;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.TestInstance.Lifecycle;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import org.mockito.junit.jupiter.MockitoExtension;
@ExtendWith(MockitoExtension.class)
public class TestControllerTest {
@Nested
@TestInstance(Lifecycle.PER_CLASS)
public class NestedTestControllerTest {
@ParameterizedTest
@MethodSource("provideKeyAndValue")
public void test(Integer key, String value) {
System.out.println(key + " " + value);
}
private Stream<Arguments> provideKeyAndValue() {
return Stream.of(
Arguments.of(1, "value1"),
Arguments.of(2, "value2"),
Arguments.of(3, "value3")
);
}
}
}
이렇게 @TestInstance
를 Lifecycle.PER_CLASS로 설정해주면 동일한 test instance에서 모든 test method를 실행할 수 있게 되며 provideKeyAndValue()를 static으로 두지 않고도 @MethodSource를 사용할 수 있게 된다.
사실 위와 같이 Unit Test를 작성해도 괜찮을지는 모르겠지만, 한 번도 접해보지 못한 어노테이션을 사용하였고 알게 되었다는 것에 의의를 둘 수 있었다.
Author And Source
이 문제에 관하여(JUnit5 @ParameterizedTest), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@jduckling_1024/JUnit5-ParameterizedTest저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)