JavaScript는 역동적 인 유형 언어로 강력한 성능 능력을 제공하지만 컴파일러는 개발자에게 도움을 줄 수 없습니다. 이러한 이유로, 우리는 JavaScript 코드를 작성하는 데 강력하고 완전한 테스트 세트가 있어야한다고 생각합니다. Angular에는 응용 프로그램을보다 쉽게 테스트 할 수있는 많은 기능이 있습니다. 우리는 테스트를 작성하지 않을 변명이 없어야합니다 (이것은 ...).
1. 문제를 혼합하지 않는 것입니다 (코드 관계가 복잡해지는 것을 피하는 것입니다 ...)
이름으로 단위 테스트는 단일 "단위"를 테스트하는 것입니다. 단위 테스트는 이러한 질문에 답하기 위해 노력합니다. 이미 논리 고려 사항에서 정확합니까? 분류 방법으로 얻은 결과가 정확합니까? 이러한 질문에 답하기 위해서는 분리하는 것이 특히 중요합니다. 정렬 방법을 테스트 할 때 DOM 요소와 같은 다른 관련 단편이나 데이터를 가져 오기위한 XHR 요청 등을 시작하는 데 관심이 없기 때문입니다. 분명히 일반적인 프로젝트에서 기능을 별도로 호출하는 것은 어렵습니다. 이 문제의 이유는 개발자가 종종 관계를 복잡하게 만들고 스 니펫을 모든 일을 할 수있는 것처럼 보이게하기 때문입니다. XHR을 통해 데이터를 가져오고 데이터를 정렬 한 다음 DOM을 조작합니다. Angular와 함께 우리는 더 나은 코드를보다 쉽게 쓸 수 있으므로 Angular는 XHR (시뮬레이션 할 수있는)의 종속성 주입을 제공하고 Angular는 또한 DOM을 조작하지 않고 모델을 정렬 할 수있는 추상화를 생성합니다. 따라서 결국 정렬 방법을 작성한 다음 테스트 할 때 분류 방법을 사용할 수있는 테스트 케이스를 통해 데이터 세트를 작성한 다음 결과 모델이 기대치를 충족하는지 확인할 수 있습니다. 테스트는 XHR이 해당 DOM을 생성하고 기능이 DOM을 올바르게 작동하는지 여부를 결정할 필요가 없습니다. Angular의 핵심 아이디어에는 코드의 테스트 가능성이 포함되어 있지만 올바른 일을해야합니다. Angular는 옳은 일을하는 방법을 단순화하기 위해 최선을 다하고 있지만 Angular는 마법이 아니기 때문에 다음 지점을 따르지 않으면 테스트 할 수없는 응용 프로그램으로 끝날 수 있습니다.
1. 종속성 주입
종속성 리소스를 얻는 방법에는 여러 가지가 있습니다. 1) 새 연산자를 사용할 수 있습니다. 2) 우리는 "Global Singleton"이라는 잘 알려진 방법을 사용합니다. 3) 레지스트리 서비스에서 요청할 수 있습니다 (그러나 레지스트리를 어떻게 얻을 수 있습니까? 다음 장을 확인할 수 있습니다). 4) 우리는 그것이 통과 될 것으로 기대할 수 있습니다.
위에 나열된 방법 중 마지막 방법 만 테스트 가능합니다.
1) 새 연산자 사용
새 연산자를 사용할 때는 기본적으로 오류가 없지만 문제는 새로 생성자를 호출하면 발신자를 유형에 영구적으로 바인딩한다는 것입니다. 예를 들어, 우리는 서버에서 일부 데이터를 얻을 수 있도록 XHR 객체를 인스턴스화하려고합니다.
함수 myclass () {this.dowork = function () {var xhr = new xrh (); xhr.open (메소드, url, true); xhr.onreadystatechange = function () {…}; xhr.send (); }}문제는 테스트 할 때 일반적으로 테스트 데이터 또는 네트워크 오류를 반환 할 수있는 가상 XHR을 인스턴스화해야한다는 것입니다. New XHR ()에게 전화함으로써 우리는 실제 XHR을 영구적으로 바인딩하며이를 교체 할 좋은 방법이 없습니다. 물론, 나쁜 치료법이 있으며 그것이 나쁜 생각임을 증명해야 할 많은 이유가 있습니다.
var OldXhr = XHR; XHR = New MockXhr () {}; myclass.dowork (); // mockxhr이 일반 매개 변수를 통해 xhr = OldXhr을 호출하는지 여부를 판단하십시오.2) 글로벌 조회
문제를 해결하는 또 다른 방법은 잘 알려진 곳에서 의존성 자원을 얻는 것입니다.
함수 myclass () {this.dowork = function () {global.xhr ({…}); };}새로운 종속 객체의 인스턴스를 생성하지 않으면 문제는 기본적으로 새로운 것과 동일하며 테스트 할 때 Global.xhr 호출을 가로 채는 좋은 방법이 없습니다. 테스트의 가장 기본적인 문제는 가상 메소드를 호출하려면 글로벌 변수를 변경하고 수정된다는 것입니다. 단점에 대한 자세한 내용은 여기를 방문하십시오. http://misko.hevery.com/code-reviewers-guide/flaw-brittle-global-state-singletons/
위의 코드는 테스트하기가 어렵 기 때문에 글로벌 상태를 수정해야합니다.
var OldXhr = global.xhr; global.xhr = function mockxhr () {…}; var myclass = new myclass (); // mockxhr가 일반적인 매개 변수를 통해 global.xhr = OldXhr을 호출하는지 여부를 판단합니다.3) 서비스 레지스트리
모든 서비스에 레지스트리가 있으면 문제를 해결 한 다음 테스트 코드에서 필요한 서비스를 교체하는 것으로 보입니다.
function myclass () {var serviceregistry = ???; this.dowork = function () {var xhr = serviceregistry.get ( "xhr"); …};}그러나 Serviceregistry는 어디에서 왔습니까? * New-Ed Up, 테스트는 테스트를위한 서비스를 재설정 할 기회가 없습니다. * 글로벌 조회 등 반환 된 서비스도 전 세계적입니다 (그러나 재설정이 더 쉬워집니다. 이는 재설정 할 글로벌 변수가 하나만 있기 때문에 더 쉽습니다.
이 방법에 따라 위의 클래스를 다음 방법으로 수정하십시오.
var oldservicelocator = global.servicelocator; global.servicelocator.set ( 'xhr', function mockxhr () {}); var myclass = new myclass (); myclass.dowork (); // mockxhr이 Global.servicelocator = OldServicelocator; //이 단계를 잊어 버리면 슬픈 일을 쉽게 일으킬 수 있습니다.4) 종속성 전달
마지막으로, 종속성 리소스를 통과 할 수 있습니다.
함수 myclass (xhr) {this.dowork = function () {xhr ({…}); };}이 코드는 XHR의 출처에주의를 기울이지 않아도되거나 XHR을 생성 한 사람은주의를 기울이지 않기 때문에 선호하는 방법입니다. 따라서 클래스 제작자는 클래스 소비자와 별도로 인코딩 될 수 있으며, 이는 생성의 책임을 논리에서 의존성 사형과 분리 할 수 있습니다.
이 수업은 테스트하기 쉽고 테스트에서 이와 같이 쓸 수 있습니다.
함수 xhrmock (args) {…} var myclass = new myclass (xhrmock); myclass.dowrok (); // 일부 판단 ...이 테스트 코드를 통해 글로벌 변수가 손상되지 않았 음을 알 수 있습니다.종속성-입지 (//www.vevb.com/article/91775.htm)는 이러한 방식으로 작성된 코드에 포함되어있어 테스트 코드를 쉽게 작성할 수 있습니다. 테스트가 가능한 코드를 작성하려면 더 잘 사용하는 것이 좋습니다.
2. 컨트롤러
논리는 모든 응용 프로그램을 독특하게 만들고 이것이 우리가 테스트하고 싶은 것입니다. 우리의 논리가 DOM 작업과 혼합되면 다음 예제만큼 테스트하기가 어렵습니다.
함수 passwordController () {// dom object var msg = $ ( '. ex1 span')에 대한 참조를 얻습니다. var input = $ ( '. ex1 input'); var 강도; this.grade = function () {msg.removeClass (강도); var pwd = input.val (); password.text (pwd); if (pwd.length> 8) {강도 = 'strong'; } else if (pwd.length> 3) {강도 = 'medium'; } else {강도 = '약한'; } msg.addclass (강도) .text (강도); }}위의 코드는 테스트를 실행할 때 올바른 DOM을 가져야하므로 테스트 할 때 문제가 발생합니다. 테스트 코드는 다음과 같습니다.
var input = $ ( '<input type = "text"/>'); var span = $ ( '<span>'); $ ( 'body'). html ( '<div>'). find ( 'div'). Append (입력); var pc = new passwordController (); input.val ( 'abc'); pc.grade (); excl (span.text ()). toequal ( '약한'); $ ( 'body'). html ( '');
각도에서 컨트롤러는 DOM 작동 논리를 엄격하게 분리하여 테스트 케이스 작성의 어려움을 크게 줄입니다. 다음 예를 살펴보십시오.
함수 passwordcntrl ($ scope) {$ scope.password = ''; $ scope.grade = function () {var size = $ scope.password.length; if (size> 8) {$ scope.strength = 'strong'; } else if (size> 3) {$ scope.strength = 'medium'; } else {$ scope.strength = '약한'; }};}테스트 코드는 간단합니다.
var pc = 새 PasswordController ($ scope); pc.password ( 'abc'); pc.grade (); explit ($ scope.strength) .toequal ( '약');
테스트 코드는 더 불연속적 일뿐 만 아니라 추적하기가 더 쉽다는 점은 주목할 가치가 있습니다. 우리는 항상 테스트 사례가 다른 관련이없는 것들을 판단하지 않고 이야기를 전하고 있다고 말했습니다.
3. 필터
필터 (http://docs.angularjs.org/api/ng.$filter)는 데이터를 사용자 친화적 인 형식으로 변환하는 데 사용됩니다. 그것들은 애플리케이션 로직에서 형식을 변환하는 책임을 분리하여 응용 프로그램 논리를 더욱 단순화하기 때문에 중요합니다.
myModule.filter ( 'length', function () {return function (텍스트) {return ( ''+(텍스트 || ''). 길이;}}); var 길이 = $ 필터 ( 'length'); expler (null)); expl (길이 ( 'abc')). toequal (3);4. 지시
5. 조롱
6. 글로벌 상태 격리
7. 선호하는 테스트 방법
8. JavaScriptTestDriver
9. 재스민
10. 샘플 프로젝트
우리는 앞으로 관련 기사를 계속 업데이트 할 것입니다. 이 사이트를 지원 해주셔서 감사합니다!