SEB_BE 56일차 - 테스팅3

subimm_·2022년 11월 10일
0

코드스테이츠

목록 보기
56/83

💡 오늘의 학습목표

  • Mockito
  • TDD

📔 Mockito

  • 테스트 세계에서의 Mock은 가짜 객체를 의미한다.
  • 단위 테스트나 슬라리읏 테스트 등에 Mock객체를 사용하는 것을 Mocking이라고 함.

📖 테스트에서 Mock 객체 사용 이유

  • 슬라이스 테스트 시 핸들러 메서드쪽만 테스트를 해야 하는데 서비스 계층을 거쳐서 데이터 액세스계층 데이터베이스까지 거쳐야 하기 때문에
  • Mock 객체를 사용하면 컨트롤러에서 Mock서비스 클래스로 거쳐서 다른 계층과 단절하여 테스트 가능

📖 Mockito ?

  • Spring Framework 자체 지원하는 Mocking 라이브러리
  • 슬라이스 테스트에 Mockito 적용
    ✔ MemberController의 postMember()테스트에 Mockito 적용

  • @MockBean 애너테이션은 애플리케이션 컨텍스트에 등록되어 있는 빈에 대한 Mockito Mock 객체를 생성하고 주입해주는 역할

    • (1) 과 같이 필드에 추가하면 해당 필드의 Bean에 대한 Mock객체 생성 후 필드에 주입
      (1)에서는 MemberService 빈에 대한 Mock 객체를 생성해서 memberService 필드에 주입
  • (2)에서 MemberMapper를 DI 받는 이유는 MockMemberService의 createMember() 에서 리턴하는 Member 객체를 생성하기 위해서

  • (3)에서 MemberMapper를 이용해 post 변수를 Member 객체로 변환

  • 실제 MemberService의 createMember()에서 회원 정보 등록 시 Stamp 정보도 등록되면 리턴값에도 포함
    따라서 MockMemberService에도 리턴값으로 Stamp가 포함된 Member 객체를 리턴하도록 (4)
    (추가하지 않으면 JSON으로 변환되는 과정 중에 Stamp에 대한 정보가 없다는 예외 발생함)

  • (5) Mockito에서 지원하는 Stubbing 메서드

    • given(memberService.createMember(Mockito.any(Member.class)))
      given() 은 Mock 객체가 특정 값을 리턴하는 동작을 지정 (when()과 동일한 기능)
      Mock 객체인 memberService 객체로 createMember() 메서드를 호출하도록 정의
      Mockito.any(Member.class)는 Mockito에서 지원하는 변수 타입 중하나
      • 실제 MemberService 클래스에서 createMember()의 파라미터 타입은 Member타입
        따라서 Mockito.any()에 Member.class 로 타입 지정
    • .willReturn(member)
      MockMemberService의 createMember()메서드가 리턴 할 Stub 데이터
      • Stubbing ?
        테스트를 위해서 Mock 객체가 항상 일정한 종작을 하도록 지정하는 것
  • 실행하면 데이터 액세스 계층 쪽의 로직은 실행이 되지 않음.

  • breakpoint로 확인 memberService 객체가 Mock 객체인것 확인

✔ MemberService의 createMember() 테스트에 Mockito 적용

  • 어디서 조회해 왔던지 상관없이 조회된 Member객체가 null이면 BusinessLogicException을 잘 던지는지 여부만 테스트
  • DB에서 회원 정보를 조회하는 memberRepository.findByEmail(email)은 Mocking 대상
  • Mocking을 통해서 Member 객체 제공
  • (1) Spring을 사용하지 않고, Junit에서 Mockito의 기능을 사용하기 위해서 (1)과 같이 애너테이션 추가해야함.
  • (2)와 같이 Mock 애너테이션 추가하면 해당 필드의 객체를 Mock 객체로 생성
  • (3) @InjectMock 애너테이션 추가한 필드에 (2)에서 생성한 Mock객체 주입
    즉 (3)의 memerService 객체는 주입 받은 memberRepository Mock 객체를 포함함.
  • (4)에서는 (2)에서 생성한 memberRepository Mock 객체로 Stubbing을 하고 있음.
    • memberRepository.findByEmail(Mockito.anyString()) 의 리턴 값으로 (5)와 같이 Optional.of(member)를 지정해서 테스트 실행시 결과는 성공.

📔 TDD

TDD(Test Driven Development, 테스트 주도 개발)

  • 테스트를 먼저 하고 구현은 그 다음에 하는 설계 기법

📖 TDD 방식으로 개발하며 TDD의 특성 알아보기

  • 로그인 인증용 패스워드 유효성 검증하는 기능 개발
    • 패스워드 유효성 검증 통과 조건
      패스워드 길이는 8~20 사이의 길이
      패스워드는 알파벳 소문자 + 알파벳 대문자 + 숫자 + 특수문자 형태로 구성
      * 알파벳 대/소문자와 숫자를 제외한 모든 문자는 특수문자라고 가정
  • 테스트 케이스 작성
  • 모든 조건에 만족하는 테스트를 먼저 진행한 뒤에 조건에 만족하지 않는 테스트를 단계적으로 진행하면서 실패하는 테스트를 점진적으로 성공시켜 간다.
  • 컴파일 에러(존재하지 않는 클래스)
  • 컴파일 에러부터 해결
  • 클래스와 메서드 생성

✔ 특수문자 실패 테스트 작성

  • 패스워드를 검증하는 조건 생성 ( 실패하는 경우 )
  • (1) 과 같이 특수문자 포함 여부 체크 후
  • (2) 에서 특수문자 포함하지 않는 경우에만 예외 던지기
  • 실패하는 테스트 -> 실패하는 테스트를 성공할 만큼의 기능 구현 -> 성공하는 테스트 -> 리팩토링 -> 실패하는 테스트와 성공하는 테스트 확인
profile
코린이의 공부 일지

0개의 댓글