아이템 52 테스팅 타입의 함정에 주의하기
📍 타입 선언 테스트
프로젝트를 공개하려면 테스트 코드를 작성하는 것은 필수이며, 타입 선언도 테스트를 거쳐야 한다. 하지만, 타입 선언을 테스트하기는 매우 어렵다. 보통, 타입 선언에 대한 테스트 코드를 작성할 때 타입스크립트가 제공하는 도구를 사용하여 단언문으로 때우는데 이런 방법에는 몇 가지 문제가 있다.
⭐️ 궁극적으로는 dtslint 또는 타입 시스템 외부에서 타입을 검사하는 유사한 도구를 사용하는 것이 더 안전하고 간단하다.
📍 예제
이 코드는 오류체크를 수행하지만 허점이 존재한다. map의 첫 번째 매개벼수에 배열이 아닌 단일 값이 있었다면 매개변수의 타입에 대한 오류는 잡을 수 있지만, 반환값에 대한 체크가 누락되어 완전한 테스트라고 할 수 없다.
이 코드는 square 함수의 실행에서 오류가 발생하지 않는지만 체크한다. 하지만 반환값에 대해서는 체크하지 않기 때문에, 실제로는 실행의 결과에 대한 테스트는 하지 않은 것이 된다. square의 구현이 잘못되어 있더라도 이 테스트를 통과하게 된다.
🔗 완전한 테스트 코드가 아닌 이유
타입 선언 파일을 테스팅할 때는 이 테스트 코드처럼 단순히 함수를 실행만하는 방식을 일반적으로 적용하는데, 그 이유는 라이브러리 구현체의 기존 테스트 코드를 복사하면 간단히 만들 수 있기 때문이다. 함수를 실행만 하는 테스트코드가 의미 없는 것은 아니지만, 실제로는 반환 타입을 체크하는 것이 훨씬 더 좋은 코드이다.
→ 반환값을 특정 타입의 변수에 할당하여 간단히 반환 타입을 체크할 수 있는 방법을 알아보자.
📍 타입 선언 테스트
🔗 테스팅을 위해 할당을 사용하는 방법
1️⃣ 불필요한 변수 만들기
일반적으로는, 변수를 도입하는 대신 헬퍼 함수를 정의한다.
2️⃣ 두 타입이 동일한지 체크하는 것이 아니라 할당 가능성을 체크하기
🔗 any
이 모듈 선언은 까다로운 테스트를 통과할 수 있는 완전한 타입 선언 파일이지만, 결과적으로는 좋지 않은 설계가 된다. 전체 모듈에 any 타입을 할당한다. → 테스트는 전부 통과하고, 타입 안전성을 포기, 해당 모듈에 속하는 모든 함수의 호출마다 암시적 any 타입을 반환하기 때문에 코드 전반에 걸쳐 타입 안전성을 지속적으로 무너뜨린다.
암시적 any 타입 발견하기
DefinitelyTyped의 타입 선언을 위한 도구는 dtslint이다. 특별한 형태의 주석을 통해 동작한다. dtslint는 심벌의 타입을 추출하여 글자 자체가 같은지 비교한다.
string|number, number|string을 다른 타입으로 인식한다. string과 any를 비교할 때도, 두 타입은 서로 간에 할당이 가능하지만 글자 자체는 다르기 때문에 다른 타입으로 인식한다.
타입 선언을 테스트하는 것은 어렵지만 몇 가지 일반적인 기법의 문제점을 인지하고, 문제점을 방지하기 위해 dtslint 같은 도구를 사용하여 타입 선언 테스트를 반드시 하자.
📍 요약
타입을 테스트할 때는 함수 타입의 동일성과 할당 가능성의 차이에 대해 알아야 한다.
콜백이 있는 함수를 테스트할 때는 콜백 매개변수의 추론된 타입을 체크해야 한다.
this
가 API의 일부분이라면 역시 테스트해야한다.타입 관련된 테스트에서
any
를 주의하고dtslint
같은 도구를 사용하는 것이 좋다.
Last updated