🎁 모든 강의 30% + 무료 강의 선물🎁

[워밍업 클럽 3기 BE code] 4주차 발자국

 

강의 수강

Mock

 

  • Dummy: 아무 것도 하지 않는 깡통 객체

  • Fake: 단순한 형태로 동일한 기능은 수행하나, 프로덕션에서 쓰기에는 부족한 객체(ex. FakeRepository)

  • Stub: 테스트에서 요청한 것에 대해 미리 준비한 결과를 제공하는 객체. 그 외에는 응답하지 않는다.

  • Spy: Stub이면서 호출된 내용을 기록하여 보여줄 수 있는 객체. 일부는 실제 객체처럼 동작시키고 일부만 Stubbing할 수 있다.

  • Mock: 행위에 대한 기대를 명세하고, 그에 따라 동작하도록 만들어진 객체

Stub vs. Mock

  • Stub: 상태 검증(State Verification)

  • Mock: 행위 검증(Behavior Verification)

     

 

더 나은 테스트를 작성하기 위한 구체적인 조언

 

1. 한 문단에 한 주제!

  • 반복문, 조건문 지양

  • Parameterized Test 활용

2. 완벽하게 제어하기

  • 현재시간, 랜덤값 등은 분리해서 상위 레벨로 올리기

3. 테스트 환경의 독립성을 보장하자.

  • 테스트가 실패하더라도 그 부분은 when, then 절이어야 함

  • given 절에서 테스트가 깨지면 왜 실패했는지 유추하기 힘들어짐

  • 테스트에서는 팩토리 메서드도 지양, 생성자나 빌더로 생성하기

4. 테스트 간 독립성을 보장하자.

  • 두 가지 이상의 테스트가 하나의 자원을 공유하면 안됨(static 변수 x)

  • 테스트는 순서와 무관해야하고 각각 독립적으로 작동해야 함

  • 하나의 인스턴스가 차례대로 변화하는 과정을 테스트하고 싶다면 DynamicTest 사용

5. 한 눈에 들어오는 Test Fixture 구성하기

  • Fixture: 고정물, 고정되어 있는 물체

  • 테스트를 위해 원하는 상태로 고정시킨 일련의 객체 (주로 given절 구성할 때)

  • setUp에서 공통된 Fixture들을 구성하고 테스트할 수 있지만, 공유 변수는 테스트간 결합도가 생기게 만들기 때문에 지양하는 것이 좋음

  • setUp에 given절이 위치해 있으면 문서로서의 기능도 사라짐

  • setUp을 구성할 때는 "각 테스트 입장에서 봤을 때, 아예 몰라도 테스트 내용을 이해하는 데에 문제가 없는가?", "수정해도 모든 테스트에 영향을 주지 않는가?" 질문을 던져볼 것

  • data.sql을 활용해서 테스트 데이터를 넣어놓을 수 있지만, 이는 데이터가 파편화되어서 무얼 테스트하는지 파악하기 어렵게 함

  • 프로젝트가 커질수록 data.sql 관리가 어려워짐

  • 프로젝트에서 필요한 빌더메서드를 만들어서 사용할 때는, 필요한 파라미터만 사용할 것

  • 빌더를 클래스마다 만들려면 힘드니까 모아서 사용하면 안될까? - 추천하지 않음

    • 실무에서 사용하는 객체는 필드가 수십개가 되는 경우도 있음

    • 그럼 한 클래스에 각자 사용하는 빌더를 계속 만들기 시작하다보면 관리가 어려워짐

    • 코틀린을 사용하면 어느정도 해소가 됨

6. Test Fixture 클렌징

  • deleteAll()은 건별로 지우는 다수 쿼리때문에 속도 저하

  • deleteAllInBatch()는 관계만 잘 생각하면 더 좋은 방법

  • @Transactional 롤백을 주로 사용하긴 함

    • Spring Batch같은 걸 사용한 Batch 통합테스트를 쓰면 여러 트랜잭션이 참여를 하기 때문에 트랜잭션 롤백이 사용하기 어려워 질 수 있음 그럴때는 deleteAllInBatch() 사용

7. @ParameterizedTest

  • 하나의 테스트케이스인데 값을 여러 개로 바꾸어가며 테스트해보고 싶을 때 사용

8. @DynamicTest

  • 하나의 환경을 설정해놓고 시나리오를 테스트하고 싶을 때

9. 테스트 수행도 비용이다. 환경 통합하기

  • 서버가 뜨는 횟수가 많아지면 시간적 비용이 큼

  • 상위 추상클래스를 만들어서 각 테스트가 상속받게 함

  • Mocking을 하면 새로운 환경이기 때문에 새로 서버가 띄워짐

    • Mocking 처리한 것들을 가장 위로 올리거나, 테스트환경을 분리해야함

Q. private 메서드의 테스트는 어떻게 하나요?

  • 할 필요가 없고, 하려고 해서도 안된다.

  • 클라이언트 입장에서는 공개 API만 알면 됨

  • private 메서드를 테스트하고 싶은 시점에 해야 할 고민 - "객체를 분리할 시점인가?"

  • 팩토리 클래스의 public 메서드로 변경해서 테스트

Q. 테스트에서만 필요한 메서드가 생겼는데 프로덕션 코드에서는 필요 없다면?

  • 만들어도 된다. 하지만 보수적으로 접근하기!

 

회고

 

테스트코드 강의를 마무리하며 워밍업스터디 3기가 끝이 났다.

강의를 수강하면서 어렵기도 했지만 유익한 팁들을 많이 얻었던 것 같다.

하지만 진도를 따라가기가 조금은 벅차서 아직 내 것으로 만들지는 못했다.

이제 내 프로젝트에 배운 부분들을 하나씩 적용해보면서 학습을 진행할 생각이다.

 

댓글을 작성해보세요.


채널톡 아이콘