Karma测试运行器中的全局变量

时间:2013-10-09 05:07:02

标签: javascript unit-testing angularjs jasmine karma-runner

我在主模板中定义了一个全局变量,我用它来存储来自后端的信息位,例如环境上下文路径。我无法在服务中移动该变量。

当我运行单元测试时,如何将该变量公开给Karma?

3 个答案:

答案 0 :(得分:58)

您可以在测试文件中声明该全局变量:

var global = "something";

describe('Your test suit', function() {
...
});

或添加一个Javascript文件,将其定义到karma.conf.js文件:

// list of files / patterns to load in the browser
files: [
   ...,
   'file-containing-the-global-variable.js'
],

答案 1 :(得分:5)

第一个解决方案在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()
);

答案 2 :(得分:5)

如果您来自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>是因为它是私有的,因此我们可以毫无错误地引用该函数,否则会出现打字稿错误;