メインテンプレートでグローバル変数が定義されており、環境コンテキストパスなどのバックエンドからの情報ビットを格納するために使用します。その変数をサービス内で移動することはできません。
単体テストを実行するときに、その変数をKarmaに公開するにはどうすればよいですか?
テストファイル内でそのグローバル変数を宣言します。
var global = "something";
describe('Your test suit', function() {
...
});
または、karma.conf.js
ファイルに定義されているJavascriptファイルを追加します。
// list of files / patterns to load in the browser
files: [
...,
'file-containing-the-global-variable.js'
],
最初の解決策はAngular 2.1.xで機能しませんでした。インポートされたサービスの変数を単に認識できませんでした。環境変数をkarma-test-shim.js
ファイルし、var
を削除して、グローバルに使用できるようにします。
私のものは次のようになります。
Error.stackTraceLimit = Infinity;
require('core-js/es6');
require('reflect-metadata');
require('zone.js/dist/zone');
require('zone.js/dist/long-stack-trace-zone');
require('zone.js/dist/proxy'),
require('zone.js/dist/sync-test'),
require('zone.js/dist/jasmine-patch');
require('zone.js/dist/async-test');
require('zone.js/dist/fake-async-test');
// Add environment variables here so that tests will inject them in source code
API_URL = 'http://localhost:8080/api/';
var appContext = require.context('../src', true, /\.spec\.ts/);
appContext.keys().forEach(appContext);
var testing = require('@angular/core/testing');
var browser = require('@angular/platform-browser-dynamic/testing');
testing.TestBed.initTestEnvironment(
browser.BrowserDynamicTestingModule,
browser.platformBrowserDynamicTesting()
);
Angular 2+から来ている場合、私が動作する唯一の方法は、window
を使用して変数またはオブジェクトをグローバルに作成することです
スクリプトからロードされたGoogle Recapthca:
<script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit" async defer></script>
この例では、Google Recaptchaを呼び出すと、grecaptcha
というグローバル変数が作成されます。
このコンポーネントでは、新しいGoogle Recaptchaをレンダリングすることにしました。もちろん、grecaptcha
を宣言しないので、declare var
を使用して、どこかで宣言されると約束する必要があります。
declare var grecaptcha;
private CreateGoogleCaptcha() {
grecaptcha.render('recaptcha', {
sitekey: this.siteKey,
callback: this.GoogleCaptchaCallback,
badge: 'inline'
});
}
private GoogleCaptchaCallback(token) {
// Handle Callback Logic
}
関数が機能するようになったので、テストを実行することにしましたが、もちろん、制御できないのでgrecaptcha
をモックしたいと思います。したがって、必要な関数を作成して追加するグローバル変数に名前を付けます。
beforeEach(() => {
fixture = TestBed.createComponent(GoogleRecaptchaComponent);
component = fixture.componentInstance;
window['grecaptcha'] = {
render() {
console.log('mocked global variable and function');
}
}
}
beforeEach
にグローバル変数を作成するのは問題ありませんが、コンポーネントから関数を呼び出す上記のようなコールバック関数がある場合はどうでしょうか?簡単にログインをテストに移動し、モックでコンポーネント関数に設定します:
it('should ', () => {
window['grecaptcha'] = {
render: function() { GoogleRecaptchaComponent['GoogleCaptchaCallback']('token'); }
};
spyOn<any>(GoogleRecaptchaComponent, 'GoogleCaptchaCallback');
GoogleRecaptchaComponent['CreateGoogleCaptcha']();
expect(GoogleRecaptchaComponent['GoogleCaptchaCallback']).toHaveBeenCalled();
});
注:spyOn<any>
:<any>
が使用されるため、関数はプライベートであるためエラーなしで参照できます。そうしないと、TypeScriptエラーが発生します。