지금 문법들이 갑자기 람다(Lambda) 식이랑 함수형 프로그래밍 스타일이 튀어나와서 당황스러우실 거예요! 😵
처음 보면 외계어 같은 게 정상입니다. 제가 아주 쉽게 “비유”를 들어서 설명해 드릴게요.
1. thenAnswer가 도대체 뭔가요? 🦜
Java
when(fakeRepo.save(any()))
.thenAnswer(invocation -> invocation.getArgument(0));
이 코드는 **“앵무새 흉내”**를 내라는 뜻입니다.
-
상황:
userRepository.save(user)메서드는 원래 **“저장된 유저 객체”**를 리턴해야 합니다. -
문제:
thenReturn(new User())라고 딱 정해버리면, 내가userA를 저장하든userB를 저장하든 무조건 똑같은 객체만 리턴되겠죠? -
해결 (
thenAnswer): “야 가짜야, 내가save(괄호)안에 넣어준 녀석(0번째 인자)을 그대로 뱉어내!” 라고 시키는 겁니다.
풀어쓰면 이렇습니다:
-
invocation: “메서드 호출 사건” 그 자체 -
.getArgument(0): 괄호 안의 **0번째 재료(입력값)**를 꺼내줘. -
결과:
save(chulsoo)를 호출하면 →chulsoo가 리턴됨. (거울 모드 🪞)
2. thenReturn vs thenAnswer 차이점 ⚔️
| 구분 | thenReturn (90% 사용) | thenAnswer (가끔 사용) |
|---|---|---|
| 비유 | 자동응답기 | 통역사 / 앵무새 |
| 동작 | 누가 뭘 물어보든 똑같은 답만 함 | 질문 내용을 듣고 그에 맞춰서 답을 만들어줌 |
| 예시 | when(..).thenReturn(true)→ 무조건 true만 뱉음 | when(..save(user)).thenAnswer(..)→ 들어온 user를 다시 뱉음 |
| 용도 | 조회 결과, 성공/실패 여부 등 고정된 값 | save()처럼 입력값을 다시 리턴해야 할 때 |
결론: 평소에는 thenReturn만 쓰다가, **“입력받은 값을 그대로 돌려줘야 할 때”**만 thenAnswer를 복붙해서 쓰세요!
3. assertThatThrownBy는 뭔가요? 💣
이건 “폭탄 제거반” 테스트입니다.
“이 코드를 실행하면 에러가 터져야 정상이야!”라고 검증하는 거죠.
Java
assertThatThrownBy(() -> userService.signup(..)) // 1. "자, 버튼 누른다? (실행)"
.isInstanceOf(RuntimeException.class) // 2. "터졌네! 근데 이거 RuntimeException 폭탄 맞아?"
.hasMessage("이미 존재하는 닉네임입니다."); // 3. "폭탄에 '이미 존재함'라고 쪽지 써있어?"
-
() -> ...: 람다식이라고 하는데, 그냥 “지금 당장 실행하지 말고, 내가 신호 주면 실행해” 라는 뜻의 포장지입니다. (바로 실행해버리면 테스트가 멈추니까 감싸둔 것) -
.isInstanceOf(..): 에러의 종류가 맞는지 확인 (예:NullPointerException인지RuntimeException인지) -
.hasMessage(..): 에러 메시지 내용이 토씨 하나 안 틀리고 똑같은지 확인
4. isEqualTo 말고 자주 쓰는 것들 (치트시트) 📝
AssertJ(assertThat)는 문법이 영어 문장 같아서 읽기 편합니다. 이것만 알면 끝입니다!
① 참/거짓, Null 체크
Java
assertThat(result).isTrue(); // true여야 해
assertThat(result).isFalse(); // false여야 해
assertThat(result).isNull(); // null이어야 해
assertThat(result).isNotNull(); // null이면 안 돼 (데이터가 있어야 해)
② 문자열(String) 검사
Java
String token = "Bearer xiaug89...";
assertThat(token).startsWith("Bearer"); // "Bearer"로 시작하니?
assertThat(token).endsWith("..."); // "..."로 끝나니?
assertThat(token).contains("aug"); // 중간에 "aug"가 들어있니?
assertThat(token).doesNotContain("admin"); // "admin"은 없어야 해!
③ 리스트(List) 검사 (엄청 자주 씀!)
Java
List<String> fruits = List.of("사과", "바나나");
assertThat(fruits).hasSize(2); // 개수가 2개니?
assertThat(fruits).isEmpty(); // 비어있니?
assertThat(fruits).contains("사과"); // "사과"가 들어있니?
assertThat(fruits).containsExactly("사과", "바나나"); // 순서까지 완벽하게 똑같니?
💡 팁:
IntelliJ에서 assertThat(변수). 찍고 나서 ctrl + space 누르면 쓸 수 있는 기능 목록이 촤라락 나옵니다. 영어 단어 뜻 그대로니까 감으로 찍어도 다 맞습니다! 😎