[워밍업 클럽 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기가 끝이 났다.
강의를 수강하면서 어렵기도 했지만 유익한 팁들을 많이 얻었던 것 같다.
하지만 진도를 따라가기가 조금은 벅차서 아직 내 것으로 만들지는 못했다.
이제 내 프로젝트에 배운 부분들을 하나씩 적용해보면서 학습을 진행할 생각이다.
댓글을 작성해보세요.