어제 모킹에 관해서 아샬님의 영상을 보고 문득 테스트하기 좋은 코드는 무엇일지 궁금해져서 검색하다가 조졸두님의 블로그 글에서 좋은 내용을 찾았다. 테스트하기 좋은 코드는 어떤 건지 한번 살펴보자!
테스트가 필요한 곳
일단 테스트가 어디에 필요한지부터 고민해보자. 우리가 핵심을 기울여서 검증해야 할 곳은 비즈니스 로직이다. 결국 도메인을 우선으로 테스트해야 한다는 것이다. UI Layer를 검증하기 위해 대부분의 시간을 쏟고 있다면 주객이 전도된것이다.
테스트를 짜기 어려운 이유
보통 테스트에서 어려움을 겪는 이유는 어려운 구현체를 테스트하려고 하기 때문이다. 결국에는 실제 코드의 구조가 잘못되었기 때문에 테스트하기가 어려워진다.
극단적으로 말하면 테스트하기 쉬운구조로 코드를짰을때 모킹도 거의 필요없다고 한다.
테스트 코드가 구현 코드의 구조를 바꿀만큼 중요한가?
그렇다고 한다. 좋은 코드는 대부분 테스트하기가 편하다. 테스트 코드를 짜기 어렵다면 실제코드가 구리다는 신호다.
실제 코드와 테스트코드의 중요성을 동등하게 생각하자.
테스트하기 좋은코드란
테스트하기 좋은코드란 무엇일까? 보통 동일한 입력을 넣으면 동일한 출력을 반환하는 코드이다.
멱등성이 보장되는 순수함수를 생각하면 좋을 것 같다.
그러면 테스트하기 어려운코드는?
비즈니스 로직이 제어할수 없는 값에 의존하는 경우
- random처럼 출력할때마다 다른 값을 반환하는 함수에 의존하는 경우
- 사용자들의 입력값에 의존해야 하는 경우
- 전역함수, 전역변수에 의존하는 경우
- 외부 sdk에 의존하는경우
이러한 경우에는 출력값이 매번 바뀌기 때문에 테스트하기 어렵다.
외부에 영향을 주는 코드
- console.log, System.out.println() 과 같은 표준 출력
- Logger 등을 사용하는 경우
- 이메일 발송, 메세지큐 등 외부로의 메세지 발송
- 데이터베이스 등에 의존하는 경우
- 외부 API에 의존하는 경우
결국 외부와의 연동이 필요하면 테스트 코드가 어려워진다.
우리의 비즈니스 로직은 항상 외부와 연결되는 부분을 바깥 레이어로 밀어내야한다!
비즈니스로직에서 제어할 수 없는 값들은 어떻게 가져다 쓸까?
의존성 주입!
제어하기 어려운 값들은 의존성 주입을 이용해서 처리해주면 좋다. 모든 함수가 제어할 수 없는 값들을 항상 함수, 메소드 인자로 받아야 한다. 스프링이 좋은 이유도 매번 의존성 주입을 이용해서 내용을 처리하기 때문에 좋은것 같기도 하다.
그러면 제어할 수 없는 값의 위치는 어디다 두면 좋을까?
최대한 진입점에 위치시켜서 테스트하기 어려운 코드들의 숫자를 줄여야 한다. 스프링에서는 컨트롤러에 위치시키면 편하다.
이번 강의에서 찾아본 테스트하기 어려운 코드
외부 API를 의존한 게 어떤 것이 있었나 고민을 해보니 axios로 요청을 처리한 부분이 떠올랐다. 데이터베이스에 존재하는 값에 따라 매번 다른 결과를 내는 코드를 설계했으므로 이 부분을 테스트상에서 순수함수로 만들어주기 위해서 아샬님께서 mocking 해주신것 같다. Service에 axios가 위치해서 그 위의 테스트도 전부 모킹을 해주어야 했는데,
axios를 service 바깥 레이어로 옮겨서 mocking을 줄이는게 좋을지 한번 고민해봐야 겠다.
'TIL' 카테고리의 다른 글
왜(22.11.01TIL) (0) | 2022.11.01 |
---|---|
부수효과(22.10.31TIL) (1) | 2022.10.31 |
모킹(22.10.29TIL) (0) | 2022.10.29 |
가고싶은 회사 찾아보기(22.10.28TIL) (0) | 2022.10.28 |
단위 테스트(22.10.27TIL) (0) | 2022.10.27 |