2017-12-22 37 views
0

나는 지불을 완료하기 위해 Authorize.nets Accept.js SDK를 사용하는 각 구성 요소가 있습니다. 사용자가 결제 화면에 있지 않으면 Accept.js 스크립트를로드하지 않으므로 구성 요소에서 onInit이라는 메서드를 통해 페이지에 스크립트를 추가합니다.Angular Accept.js breaking unit tests '참조 오류 : 수락이 정의되지 않았습니다.'

이 some.component.ts

ngOnInit { 
    this.addAcceptJsScript(); 
} 

private addAcceptJsScript(): void { 
    const element = document.createElement('script'); 
    element.src = environment.acceptJsUrl; 
    element.type = 'text/javascript'; 
    document.getElementsByTagName('head')[0].appendChild(element); 
} 

some.service.ts

declare var Accept: any; 

@Injectable() 
export class SomeService { 
    private sendPaymentToAuthNet(paymentPayload): void { 
    Accept.dispatchData(paymentPayload, this.handleAuthNetResponse); 
    } 
} 

스크립트가 DOM에로드 될 때 이것은 누구나 잘 작동 때 사용할 수있는 구성 요소는 Accept API를 사용하는 서비스를 호출합니다.

그러나 API를 사용하는 서비스의 내 단위 테스트는 이 어떤 코드 라인을 테스트 할 때 Accept.dispatchData(...)이라는 테스트 오류를 ​​내고 이라는 코드를 테스트하려고 할 때 '참조 오류 : 수락이 정의되지 않았습니다.'라는 참조를 가지고 있지 않습니다..

나는 여러 가지 방법으로 Accept를 조롱했지만 그 중 누구도 시험에 응하지 않았습니다. 내 모의목 Accept을 서비스에 삽입하면 코드가 코드를 사용할 때 선언됩니다.

답변

0

테스트 문제는 일반적으로 응용 프로그램 설계의 결함을 나타냅니다.

document은 실제 요소에 스크립트 요소를 추가하지 않으려면 어떤 시점에서 조롱을 받아야하므로 공급자 여야합니다. document 글로벌 대신 구성 요소에 주입 할 수있는 공급자가 이미 DOCUMENT입니다. 그리고 테스트 베드에서 조롱 : createElementgetElementsByTagName 재스민 스파이가 구성해야

{ 
    provide: DOCUMENT, 
    useValue: jasmine.createSpyObj('document', ['createElement', 'getElementsByTagName']) 
} 

적절한 모의 개체를 반환 할 수 있습니다.

Accept도 테스트 가능성을 이유로 제공해야합니다. 이 값은 this answer과 같이 window['Accept']에 할당되고 테스트 베드에서 조롱 될 수 있습니다. 난 그냥 내 파일의 Accept.js CDN의 경로를 포함 할 필요

0

는 karma.config

files: [ 
    { pattern: './src/test.ts', watched: false }, 
    { pattern: './node_modules/@angular/material/prebuilt-themes/indigo-pink.css', included: true, watched: true }, 
    { pattern: 'https://jstest.authorize.net/v1/Accept.js', nonull: true } 
] 
+0

난 당신이 단위 테스트가 아닌 통합을 실행하는 것을 기대에서 객체. 단위 테스트에서는 실제 작업을 테스트하는 것이 격리를 파괴하기 때문에 바람직하지 않습니다. – estus

+0

나는 그것을 테스트하지 않고있다. 정의가 필요하다. – efarley

+0

요점은 잠재적 인 부작용으로 인해 실제 Accept.dispatchData (더 중요한 것은 document.createElement)가 단위 테스트에서 호출 될 기회조차 없을 것입니다. 이것은 DI가 도와 주어야하는 것입니다. 또 다른 방법은 beforeEach에서 window.Accept를 정의하는 것입니다.이 방법은 Angular보다 덜 관용적입니다. – estus