@ParameterizedTest@ValueSource(strings ={"q","qwerasdfzxcv","qq23"})@DisplayName("잘못된 이름 형식은 예외가 발생한다")voidinvalidName_throwsException(String invalidName){assertThatThrownBy(()->newUser(VALID_EMAIL, invalidName, password)).isInstanceOf(IllegalArgumentException.class);}// 숫자 타입@ParameterizedTest@ValueSource(ints ={1,2,3,10,100})voidpositiveNumbers_areValid(int number){assertThat(validator.isPositive(number)).isTrue();}// 지원 타입: strings, ints, longs, doubles, booleans, chars, bytes, shorts, floats
@ParameterizedTest@CsvSource({"홍길동, 20, true",// 이름, 나이, 유효 여부"김철수, 17, false","이영희, 100, true"})@DisplayName("나이에 따라 성인 여부가 다르다")voidcheckAdult(String name,int age,boolean expected){assertThat(validator.isAdult(age)).isEqualTo(expected);}// 특수문자 포함 시 작은따옴표로 감싸기@ParameterizedTest@CsvSource({"'Spring, Boot', PUBLISHED",// 쉼표 포함 제목"제목, DRAFT"})voidparsePost(String title,String status){Post post = postService.create(title, status);assertThat(post.getTitle()).isEqualTo(title);}
// 다른 클래스에 있는 경우 클래스명#메서드명 지정@MethodSource("com.example.TestDataFactory#provideInvalidCommands")
enumPostStatus{ DRAFT, PUBLISHED, ARCHIVED }@ParameterizedTest@EnumSource(PostStatus.class)@DisplayName("모든 PostStatus로 게시글을 생성할 수 있다")voidcreatePost_withAllStatuses(PostStatus status){Post post = postService.create("제목", status);assertThat(post.getStatus()).isEqualTo(status);}// 특정 값만 포함/제외@ParameterizedTest@EnumSource(value =PostStatus.class, names ={"PUBLISHED","ARCHIVED"})voidpublishedOrArchivedPost_isVisible(PostStatus status){assertThat(status.isVisible()).isTrue();}@ParameterizedTest@EnumSource(value =PostStatus.class, mode =EnumSource.Mode.EXCLUDE, names ="DRAFT")voidnonDraftPost_canBeIndexed(PostStatus status){assertThat(postIndexer.canIndex(status)).isTrue();}
@ParameterizedTest@NullAndEmptySource// null과 "" 두 번 실행@DisplayName("제목이 null이거나 빈 문자열이면 예외가 발생한다")voidnullOrEmptyTitle_throwsException(String title){assertThatThrownBy(()-> postService.create(title,"내용")).isInstanceOf(IllegalArgumentException.class);}// @NullSource, @EmptySource 각각 사용도 가능// @NullAndEmptySource + @ValueSource 조합@ParameterizedTest@NullAndEmptySource@ValueSource(strings ={" ","\t","\n"})// 공백 문자들도 포함voidblankTitle_throwsException(String title){assertThatThrownBy(()-> postService.create(title,"내용")).isInstanceOf(IllegalArgumentException.class);}
@ParameterizedTest(name ="[{index}] {0}으로 생성 시 예외 발생")@ValueSource(strings ={"q","qwerasdfzxcv","qq23"})voidinvalidName_throwsException(String name){...}// 출력: [1] q으로 생성 시 예외 발생// [2] qwerasdfzxcv으로 생성 시 예외 발생// [3] qq23으로 생성 시 예외 발생
@DisplayName("PostService 유효성 검증 테스트")classPostValidationTest{privatePostService postService =newPostService(newFakePostRepository());@ParameterizedTest@CsvSource({"1자 제목, false","적절한 제목, true","열다섯자를초과하는긴제목이야, false"})@DisplayName("제목 길이에 따라 유효성 결과가 다르다")voidvalidateTitle(String title,boolean expected){assertThat(postService.isValidTitle(title)).isEqualTo(expected);}}