JUnit 5 매개 변수 화 테스트 의 몇 가지 방식 을 상세 하 게 설명 합 니 다.
16632 단어 JUnit5매개 변수 화 테스트
의지 하 다
JUnit 5 는
junit-jupiter-params
의존 도 를 추가 해 야 매개 변 수 를 사용 할 수 있 습 니 다.
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<version>5.7.2</version>
<scope>test</scope>
</dependency>
단순 예시@ParameterizedTest
매개 변수 화 테스트 를 정의 하고@ValueSource
매개 변수 값 을 정의 합 니 다.
@ParameterizedTest
@ValueSource(strings = { "racecar", "radar", "able was I ere I saw elba" })
void palindromes(String candidate) {
assertTrue(StringUtils.isPalindrome(candidate));
}
실행 결과:
palindromes(String) ✔
├─ [1] candidate=racecar ✔
├─ [2] candidate=radar ✔
└─ [3] candidate=able was I ere I saw elba ✔
매개 변수 값 은 테스트 방법의 매개 변수 목록 과 일치 하고 순서대로 값 을 부여 합 니 다.여기 서 모두 3 개의 테스트 가 발생 했 습 니 다.일곱 가지 방식
1
@ValueSource
@ValueSource
는 가장 간단 한 매개 변수 화 방식 으로 하나의 배열 로 다음 과 같은 데이터 형식 을 지원 합 니 다.
@ParameterizedTest
@ValueSource(ints = { 1, 2, 3 })
void testWithValueSource(int argument) {
assertTrue(argument > 0 && argument < 4);
}
2 Null and Empty Sources@NullSource
값 은 null 입 니 다.기원 유형의 테스트 방법 에 사용 할 수 없습니다.
@EmptySource
값 이 비어 있 고 테스트 방법의 매개 변수 류 에 따라 데이터 유형 을 결정 합 니 다.지원java.lang.String
,java.util.List
,java.util.Set
,java.util.Map
,기원 유형 배열int[]
,char[][]
등,대상 배열String[]
,Integer[][]
등)@NullAndEmptySource
앞의 두 개 를 결합 시 켰 다.예시:
@ParameterizedTest
@NullSource
@EmptySource
@ValueSource(strings = { " ", " ", "\t", "
" })
void nullEmptyAndBlankStrings(String text) {
assertTrue(text == null || text.trim().isEmpty());
}
등가:
@ParameterizedTest
@NullAndEmptySource
@ValueSource(strings = { " ", " ", "\t", "
" })
void nullEmptyAndBlankStrings(String text) {
assertTrue(text == null || text.trim().isEmpty());
}
3 @EnumSource
매개 변수 화 된 값 은 매 거 진 형식 입 니 다.예시:
@ParameterizedTest
@EnumSource
void testWithEnumSourceWithAutoDetection(ChronoUnit unit) {
assertNotNull(unit);
}
그 중 크 로 노 유닛 은 날짜 매 거 진 클래스 입 니 다.ChronoUnit 은 인터페이스 TemporalUnit 의 실현 클래스 입 니 다.테스트 방법의 매개 변수 가 TemporalUnit 이면
@EnumSource
에 값 을 더 해 야 합 니 다.
@ParameterizedTest
@EnumSource(ChronoUnit.class)
void testWithEnumSource(TemporalUnit unit) {
assertNotNull(unit);
}
JUnit 5 가@EnumSource
의 기본 값 의 유형 을 매 거 진 형식 으로 규정 하기 때문이다.names 속성 은 어떤 특정한 매 거 진 값 을 사용 할 지 지정 합 니 다:
@ParameterizedTest
@EnumSource(names = { "DAYS", "HOURS" })
void testWithEnumSourceInclude(ChronoUnit unit) {
assertTrue(EnumSet.of(ChronoUnit.DAYS, ChronoUnit.HOURS).contains(unit));
}
mode 속성 은 사용 모드 를 지정 하 는 데 사 용 됩 니 다.예 를 들 어 어떤 매 거 진 값 을 제외 합 니까?
@ParameterizedTest
@EnumSource(mode = EXCLUDE, names = { "ERAS", "FOREVER" })
void testWithEnumSourceExclude(ChronoUnit unit) {
assertFalse(EnumSet.of(ChronoUnit.ERAS, ChronoUnit.FOREVER).contains(unit));
}
예 를 들 어 정규 매 칭 을 사용 합 니 다.
@ParameterizedTest
@EnumSource(mode = MATCH_ALL, names = "^.*DAYS$")
void testWithEnumSourceRegex(ChronoUnit unit) {
assertTrue(unit.name().endsWith("DAYS"));
}
4 @MethodSource
매개 변수 값 은 factory 방법 이 고 factory 방법 은 매개 변 수 를 가 져 갈 수 없습니다.예시:
@ParameterizedTest
@MethodSource("stringProvider")
void testWithExplicitLocalMethodSource(String argument) {
assertNotNull(argument);
}
static Stream<String> stringProvider() {
return Stream.of("apple", "banana");
}
@TestInstance(Lifecycle.PER_CLASS)
생명주기 가 아니면 factory 방법 은 static 이 어야 합 니 다.factory 방법의 반환 값 은Stream
로 전환 할 수 있 는 유형 이다.예 를 들 어Stream
,DoubleStream
,LongStream
,IntStream
,Collection
,Iterator
,대상 배열 또는 기본 유형 배열 이다.예 를 들 어:
@ParameterizedTest
@MethodSource("range")
void testWithRangeMethodSource(int argument) {
assertNotEquals(9, argument);
}
static IntStream range() {
return IntStream.range(0, 20).skip(10);
}
Iterable
의 속성 을 생략 하면 JUnit Jupiter 는 테스트 방법 과 같은 이름 의 factory 방법 을 찾 습 니 다.예 를 들 어:
@ParameterizedTest
@MethodSource
void testWithDefaultLocalMethodSource(String argument) {
assertNotNull(argument);
}
static Stream<String> testWithDefaultLocalMethodSource() {
return Stream.of("apple", "banana");
}
테스트 방법 에 여러 개의 인자 가 있다 면 factory 방법 도 여러 개 를 되 돌려 야 합 니 다.
@ParameterizedTest
@MethodSource("stringIntAndListProvider")
void testWithMultiArgMethodSource(String str, int num, List<String> list) {
assertEquals(5, str.length());
assertTrue(num >=1 && num <=2);
assertEquals(2, list.size());
}
static Stream<Arguments> stringIntAndListProvider() {
return Stream.of(
arguments("apple", 1, Arrays.asList("a", "b")),
arguments("lemon", 2, Arrays.asList("x", "y"))
);
}
이 중@MethodSource
은 Arguments 인터페이스의 static factory method 로 바 꿀 수도 있다arguments(Object…)
.factory 방법 도 테스트 클래스 외부 방지:
package example;
import java.util.stream.Stream;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
class ExternalMethodSourceDemo {
@ParameterizedTest
@MethodSource("example.StringsProviders#tinyStrings")
void testWithExternalMethodSource(String tinyString) {
// test with tiny string
}
}
class StringsProviders {
static Stream<String> tinyStrings() {
return Stream.of(".", "oo", "OOO");
}
}
5 Arguments.of(Object…)
매개 변수 화 된 값 은 csv 형식의 데이터(기본 쉼표 구분)입 니 다.예 를 들 어:
@ParameterizedTest
@CsvSource({
"apple, 1",
"banana, 2",
"'lemon, lime', 0xF1"
})
void testWithCsvSource(String fruit, int rank) {
assertNotNull(fruit);
assertNotEquals(0, rank);
}
delimiter 속성 은 구분 문 자 를 설정 할 수 있 습 니 다.delimiterString 속성 은 char 대신 구분자 문자열 을 설정 할 수 있 습 니 다.더 많은 입 출력 예 는 다음 과 같다.
null 이 인용 한 목표 유형 이 기본 형식 이 라면 이상
@CsvSource
을 보고 합 니 다.6
ArgumentConversionException
말 그대로 로 컬 csv 파일 을 데이터 원본 으로 선택 하 십시오.예시:
@ParameterizedTest
@CsvFileSource(resources = "/two-column.csv", numLinesToSkip = 1)
void testWithCsvFileSourceFromClasspath(String country, int reference) {
assertNotNull(country);
assertNotEquals(0, reference);
}
@ParameterizedTest
@CsvFileSource(files = "src/test/resources/two-column.csv", numLinesToSkip = 1)
void testWithCsvFileSourceFromFile(String country, int reference) {
assertNotNull(country);
assertNotEquals(0, reference);
}
delimiter 속성 은 구분 문 자 를 설정 할 수 있 습 니 다.delimiterString 속성 은 char 대신 구분자 문자열 을 설정 할 수 있 습 니 다.특히 주의해 야 할 것 은@CsvFileSource
시작 하 는 길드 가 주석 으로 여 겨 져 생략 되 었 다 는 점 이다.7
#
사용자 정의 Arguments Provider.예시:
@ParameterizedTest
@ArgumentsSource(MyArgumentsProvider.class)
void testWithArgumentsSource(String argument) {
assertNotNull(argument);
}
public class MyArgumentsProvider implements ArgumentsProvider {
@Override
public Stream<? extends Arguments> provideArguments(ExtensionContext context) {
return Stream.of("apple", "banana").map(Arguments::of);
}
}
MyArguments Provider 는 외부 클래스 나 static 내부 클래스 여야 합 니 다.매개 변수 형식 변환
암시 적 변환
JUnit Jupiter 는 String 타 입 을 암시 적 으로 변환 합 니 다.예 를 들 면:
@ParameterizedTest
@ValueSource(strings = "SECONDS")
void testWithImplicitArgumentConversion(ChronoUnit argument) {
assertNotNull(argument.name());
}
더 많은 변환 예시:String 을 사용자 정의 대상 으로 변환 할 수도 있 습 니 다.
@ParameterizedTest
@ValueSource(strings = "42 Cats")
void testWithImplicitFallbackArgumentConversion(Book book) {
assertEquals("42 Cats", book.getTitle());
}
public class Book {
private final String title;
private Book(String title) {
this.title = title;
}
public static Book fromTitle(String title) {
return new Book(title);
}
public String getTitle() {
return this.title;
}
}
JUnit Jupiter 는@ArgumentsSource
방법 을 찾 아Book.fromTitle(String)
값 을 입력 한 후 String 유형 을 Book 형식 으로 변환 합 니 다.변 환 된 factory 방법 은 하나의 String 매개 변 수 를 받 아들 이 는 구조 방법 일 수도 있 고 하나의 String 매개 변 수 를 받 아들 여 목표 유형 을 되 돌려 주 는 일반적인 방법 일 수도 있 습 니 다.상세 한 규칙 은 다음 과 같다(공식 원문).현식 변환
명시 적 변환 은 사용
@ValueSource
주석 이 필요 합 니 다.
@ParameterizedTest
@EnumSource(ChronoUnit.class)
void testWithExplicitArgumentConversion(
@ConvertWith(ToStringArgumentConverter.class) String argument) {
assertNotNull(ChronoUnit.valueOf(argument));
}
그리고 Argument Converter 를 실현 합 니 다.
public class ToStringArgumentConverter extends SimpleArgumentConverter {
@Override
protected Object convert(Object source, Class<?> targetType) {
assertEquals(String.class, targetType, "Can only convert to String");
if (source instanceof Enum<?>) {
return ((Enum<?>) source).name();
}
return String.valueOf(source);
}
}
단순 한 유형 전환 이 라면 TypedArgument Converter 를 실현 하면 됩 니 다.
public class ToLengthArgumentConverter extends TypedArgumentConverter<String, Integer> {
protected ToLengthArgumentConverter() {
super(String.class, Integer.class);
}
@Override
protected Integer convert(String source) {
return source.length();
}
}
JUnit Jupiter 는 자바 타임 아 그 먼 트 컨버터 하나만 내 장 했 습 니 다.@ConvertWith
을 통 해 사용 합 니 다.
@ParameterizedTest
@ValueSource(strings = { "01.01.2017", "31.12.2017" })
void testWithExplicitJavaTimeConverter(
@JavaTimeConversionPattern("dd.MM.yyyy") LocalDate argument) {
assertEquals(2017, argument.getYear());
}
매개 변수 집합테스트 방법의 여러 매개 변 수 는 Argument sAccessor 매개 변수 로 집합 한 다음 get 을 통 해 값 을 추출 할 수 있 습 니 다.예제:
@ParameterizedTest
@CsvSource({
"Jane, Doe, F, 1990-05-20",
"John, Doe, M, 1990-10-22"
})
void testWithArgumentsAccessor(ArgumentsAccessor arguments) {
Person person = new Person(arguments.getString(0),
arguments.getString(1),
arguments.get(2, Gender.class),
arguments.get(3, LocalDate.class));
if (person.getFirstName().equals("Jane")) {
assertEquals(Gender.F, person.getGender());
}
else {
assertEquals(Gender.M, person.getGender());
}
assertEquals("Doe", person.getLastName());
assertEquals(1990, person.getDateOfBirth().getYear());
}
Aggregator 를 사용자 정의 할 수도 있 습 니 다.
public class PersonAggregator implements ArgumentsAggregator {
@Override
public Person aggregateArguments(ArgumentsAccessor arguments, ParameterContext context) {
return new Person(arguments.getString(0),
arguments.getString(1),
arguments.get(2, Gender.class),
arguments.get(3, LocalDate.class));
}
}
그리고@JavaTimeConversionPattern
를 통 해 사용 합 니 다.
@ParameterizedTest
@CsvSource({
"Jane, Doe, F, 1990-05-20",
"John, Doe, M, 1990-10-22"
})
void testWithArgumentsAggregator(@AggregateWith(PersonAggregator.class) Person person) {
// perform assertions against person
}
조합 주 해 를 통 해 우 리 는 코드 를 더욱 간소화 할 수 있다.
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
@AggregateWith(PersonAggregator.class)
public @interface CsvToPerson {
}
@ParameterizedTest
@CsvSource({
"Jane, Doe, F, 1990-05-20",
"John, Doe, M, 1990-10-22"
})
void testWithCustomAggregatorAnnotation(@CsvToPerson Person person) {
// perform assertions against person
}
사용자 정의 디 스 플레이 이름매개 변수 화 테스트 로 생 성 된 test,JUnit Jupiter 는 기본 이름 을 정 했 습 니 다.name 속성 을 통 해 사용자 정의 할 수 있 습 니 다.
예시:
@DisplayName("Display name of container")
@ParameterizedTest(name = "{index} ==> the rank of ''{0}'' is {1}")
@CsvSource({ "apple, 1", "banana, 2", "'lemon, lime', 3" })
void testWithCustomDisplayNames(String fruit, int rank) {
}
결과:
Display name of container ✔
├─ 1 ==> the rank of 'apple' is 1 ✔
├─ 2 ==> the rank of 'banana' is 2 ✔
└─ 3 ==> the rank of 'lemon, lime' is 3 ✔
표시 하려 면@AggregateWith
두 겹'apple'
을 사용 해 야 합 니 다.name 은 Message Format 이기 때 문 입 니 다.자리 차지 문자 설명 은 다음 과 같 습 니 다.
작은 매듭
본 고 는 JUnit 5 매개 변수 화 테스트 의 7 가지 방식 을 소개 했다.각각
''apple''
,Null and Empty Sources,@ValueSource
,@EnumSource
,@MethodSource
,@CsvSource
,@CsvFileSource
로 자바 문법 에 치 우 쳐 JUnit 단원 테스트 프레임 워 크 의 특징 에 부합된다.또 JUnit Jupiter 의 매개 변수 유형 변환 과 매개 변수 집합 도 소개 했다.마지막 으로 매개 변수 화 테스트 의 이름 을 사용자 정의 하려 면 name 속성 을 사용 하여 구현 할 수 있 습 니 다.참고 자료:
https://junit.org/junit5/docs/current/user-guide/#writing-tests-parameterized-tests
JUnit 5 매개 변수 화 테스트 의 몇 가지 방식 에 대한 상세 한 설명 을 담 은 이 글 은 여기까지 입 니 다.더 많은 JUnit 5 매개 변수 화 테스트 내용 은 저희 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 읽 어 주시 기 바 랍 니 다.앞으로 많은 응원 부탁드립니다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
JUnit5 사용하기3JUnit5는 각 테스트 메서드 마다 새로운 클래스의 인스턴스를 생성한다. 기본 전략이라는건 전략을 바꿀 수 있다는 의미이기도 하다. 인스턴스의 해시값을 찍어보면 서로 다른 인스턴스라는걸 확인할 수 있다. 만약 이 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.