원문: https://blog.boot.dev/clean-code/writing-good-unit-tests-dont-mock-database-connections/
Writing Good Unit Tests; Don't Mock Database Connections
Unit tests are incredibly important to us as developers because they allow us to demonstrate the correctness of the code we’ve written.
blog.boot.dev
What is a unit test?
코드의 일부분을 테스트하는 것이다. 그 목적을 고려하면 코드를 테스트 가능한 수준에서 작은 단위로 작성하는 것이 좋을 것이다.
Good code is easier to test
함수를 작성할 때 작은 단위로, 함수 자체의 목적을 이루는 순수한 함수(ideally pure fucntion)로 작성하자.
쉬운 코드일 수록 테스트 하기 쉽다.
Unit tests shouldn’t depend on infrastructure
인프라에 의존하지 않는 함수를 만들어 테스트 할 때 infra와 관련된 설정을 거치지 않도록 하자.
예를 들어 회원가입하는 API가 한 함수에서 이루어진다고 가정해보자.
해당 함수는 총 3가지 기능을 수행한다.
1. 유효성 검사 2. 비밀번호 해시화 3. db에 저장
해당 함수를 test하게 된다면 총 3가지 기능을 다 점검해야 하기 때문에
test 코드는 hash화하는 crypto libray 뿐만 아니라 db와의 connection을 설정해야한다.
세 기능을 쪼개서 각각의 함수를 만든다고 가정해보자.
정작 test가 필요한 것은 1. 유효성 검사 기능에만 해당한다.
2. 비밀번호 해쉬화 기능은 사용한 crypto library를 믿는 편이 낫다. 어차피 쓸 것 아닌가?
3. db에 저장하는 기능이 query를 생성하는 기능이라 가정한다면, 오히려 이것을 검증할 필요는 더더욱 없다.
결론은 최대한 큰 함수를 작게 쪼개서(break our large functions into smaller encapsulated units) 테스팅 코드를 쉽게 작성하도록 하자는 것이다.
Don’t mock your external dependencies either
논쟁의 여지가 있는 주제이다. 작성자는 db와 api를 mocking하는 관습이 좋지 않다고 생각한다. 이에 대한 해결책으로서 가능한 작은 단위로 함수를 쪼개는 리팩토링을 언급했다.
mocking database는 다음과 같은 이유로 올바르지 않은 접근이라 생각한다.
- mock db는 product에 사용되지 않는다. 그러한 db에 대한 test는 의미가 없다.
(the biggest problem with mocking is that there are execution paths being tested that never are taken in production.) - mocking 접근은 테스트 커버리지(전체 코드 중 테스트가 수행된 범위로 테스트의 충분함을 의미함)가 높은 통계적 결과를 가져올 순 있지만 테스트는 보안에도 민감해져야 한다.
* 의역이 오해를 가져올 수 있으니 원문을 첨부합니다.
We technically have better “test coverage” with this approach, but our tests aren’t actually any more robust. We get a false sense of security. * - 테스팅 코드가 길어질 수록 real code는 interface 속으로 더욱 추상화되기에, 찾기 어려워진다.
Don’t test your dependencies, ensure they pass their own tests
앞서 언급한 crypto library를 이왕 쓰는거 library를 믿자는 논지.
의존하는 library의 코드를 테스트하는데 시간을 들이기 보단 내가 작성한 코드를 테스트하는데 더 신경쓰자.
Tips
실제 databse에서 test하는 것이 걱정된다면 다음 순서로 테스팅 절차를 밟아라.
db schema 생성 -> insert -> update -> delete -> db 초기화
사견
1. mock data를 사용하여 test를 할까 말까 고민하다 발견한 article인데, 결국 code 작성의 본질적인 부분을 다시 돌아보게 되었다. 최대한 capsule화하고 함수를 쪼개는 것. 반성했다.
2. library를 검증할 필요가 없다는 주장에서 납득이 되지 않는 부분이 있다. npm, node, library 간의 version 충돌 등 다양한 상황에서 버그가 발생할 여지가 있다. 또한 사용자가 library에 기여할 수 있는 기술 발전의 기회를 놓칠 수 있지 않은가?
3. 한편 테스팅 코드를 작성하는데 시간을 적게 할애하자, 테스트를 쉽게하자라는 방향성에는 매우 공감한다. 믿을 수 있는 library는 검증을 skip하는 것도 고려해봄직 하다.
번역 상의 오류가 존재할 수 있으니 원문도 꼬옥 읽어보세요!
오류는 댓글로 알려주시면 감사합니다 : )
'Articles' 카테고리의 다른 글
[요약] HTTP 역사 (0) | 2022.09.11 |
---|