지금 문법들이 갑자기 람다(Lambda) 식이랑 함수형 프로그래밍 스타일이 튀어나와서 당황스러우실 거예요! 😵

처음 보면 외계어 같은 게 정상입니다. 제가 아주 쉽게 “비유”를 들어서 설명해 드릴게요.


1. thenAnswer가 도대체 뭔가요? 🦜

Java

when(fakeRepo.save(any()))
    .thenAnswer(invocation -> invocation.getArgument(0));

이 코드는 **“앵무새 흉내”**를 내라는 뜻입니다.

  • 상황: userRepository.save(user) 메서드는 원래 **“저장된 유저 객체”**를 리턴해야 합니다.

  • 문제: thenReturn(new User())라고 딱 정해버리면, 내가 userA를 저장하든 userB를 저장하든 무조건 똑같은 객체만 리턴되겠죠?

  • 해결 (thenAnswer): “야 가짜야, 내가 save(괄호) 안에 넣어준 녀석(0번째 인자)을 그대로 뱉어내!” 라고 시키는 겁니다.

풀어쓰면 이렇습니다:

  1. invocation: “메서드 호출 사건” 그 자체

  2. .getArgument(0): 괄호 안의 **0번째 재료(입력값)**를 꺼내줘.

  3. 결과: 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 누르면 쓸 수 있는 기능 목록이 촤라락 나옵니다. 영어 단어 뜻 그대로니까 감으로 찍어도 다 맞습니다! 😎