2017-12-22 11 views
0

私は、支払いを完了するためにAuthorize.nets Accept.js SDKを使用する角度成分を持っています。ユーザーが支払い画面にいない限り、Accept.jsスクリプトをロードしたくないため、コンポーネント内のonInitというメソッドを使用してスクリプトをページに追加します。角型Accept.js破損ユニットテスト '参照エラー:受け入れが定義されていません'

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が何であるかについてのリファレンスを持っていません。'参照エラー:受け入れが定義されていません。

私はさまざまな方法でAcceptを試してみましたが、どれもテストで利用できません。コードを使用しようとしたときに宣言されるように、私のモックAcceptをサービスに挿入するにはどうすればいいですか?

答えて

0

通常、テストの問題はアプリケーション設計の欠陥を示します。

documentは、実際のDOMにスクリプト要素を追加することを避けるために、ある時点で偽装されることになっているため、プロバイダーである必要があります。 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

関連する問題