web-dev-qa-db-ja.com

Karmaテストランナーのグローバル変数

メインテンプレートでグローバル変数が定義されており、環境コンテキストパスなどのバックエンドからの情報ビットを格納するために使用します。その変数をサービス内で移動することはできません。

単体テストを実行するときに、その変数をKarmaに公開するにはどうすればよいですか?

34
Mimo

テストファイル内でそのグローバル変数を宣言します。

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'
],
59
Michael Benford

最初の解決策は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()
);
5
occasl

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エラーが発生します。

5
L1ghtk3ira