"공용 API 만 단위 테스트"하는 것이 좋은 목표이지만, 간단하지 않은 경우가 있으며 API 또는 단위 테스트 중 하나를 타협하는 것 중에서 선택하는 느낌이 드는 경우가 있습니다. 당신은 이것이 바로 당신이 요구하는 것이기 때문에 이미 알고 있습니다. 그래서 나는 그것에 들어 가지 않을 것입니다. :)
TypeScript에서 단위 테스트를 위해 개인 멤버에 액세스 할 수있는 몇 가지 방법을 발견했습니다. 이 수업을 고려하십시오.
class MyThing {
private _name:string;
private _count:number;
constructor() {
this.init("Test", 123);
}
private init(name:string, count:number){
this._name = name;
this._count = count;
}
public get name(){ return this._name; }
public get count(){ return this._count; }
}
클래스 멤버 TS를 제한 액세스를 사용하더라도 private
, protected
, public
이 JS있는 것은 아니기 때문에, 컴파일 된 JS, 아니 개인 회원이 없습니다. TS 컴파일러에만 사용됩니다. 그 때문에:
any
액세스 제한에 대해 경고하지 않도록 컴파일러를 주장 하고 이스케이프 처리 할 수 있습니다 .
(thing as any)._name = "Unit Test";
(thing as any)._count = 123;
(thing as any).init("Unit Test", 123);
이 접근법의 문제점은 컴파일러가 단순히 당신이 무엇을하고 있는지 전혀 알지 any
못하므로 원하는 유형 오류가 발생하지 않는다는 것입니다.
(thing as any)._name = 123; // wrong, but no error
(thing as any)._count = "Unit Test"; // wrong, but no error
(thing as any).init(0, "123"); // wrong, but no error
리팩토링이 더 어려워 질 것입니다.
배열 액세스 ( []
)를 사용 하여 개인 멤버를 확보 할 수 있습니다 .
thing["_name"] = "Unit Test";
thing["_count"] = 123;
thing["init"]("Unit Test", 123);
펑키하게 보이지만 TSC는 실제로 직접 액세스 한 것처럼 유형을 확인합니다.
thing["_name"] = 123; // type error
thing["_count"] = "Unit Test"; // type error
thing["init"](0, "123"); // argument error
솔직히 말해서 이것이 왜 효과가 있는지 모르겠습니다. 이것은 의도적 인 "탈출 해치" 로, 유형 안전을 잃지 않으면 서 개인 회원에게 액세스 할 수 있습니다. 이것이 바로 당신이 단위 테스트를 원하는 것입니다.
다음은 TypeScript Playground 의 실제 예제입니다 .
TypeScript 2.6 편집
다음과 같은 다른 옵션 은 다음 줄의 모든 오류를 간단히 억제하는 사용하는 것입니다 // @ts-ignore
( TS 2.6에 추가됨 ).
// @ts-ignore
thing._name = "Unit Test";
이것의 문제는 다음 줄의 모든 오류를 억제한다는 것입니다.
// @ts-ignore
thing._name(123).this.should.NOT.beAllowed("but it is") = window / {};
나는 개인적 @ts-ignore
으로 코드 냄새를 고려 하고 문서에서 말하는 것처럼 :
이 주석은 매우 드물게 사용하는 것이 좋습니다 . 【강조 오리지날】