Глобальные переменные в средстве запуска тестов Karma

У меня есть глобальная переменная, определенная в моем основном шаблоне, которую я использую для хранения битов информации из серверной части, таких как путь контекста среды. Я не могу переместить эту переменную внутри службы.

Как я могу открыть эту переменную для Karma при запуске модульных тестов?


person Mimo    schedule 09.10.2013    source источник


Ответы (3)


Вы либо объявляете эту глобальную переменную в своем тестовом файле:

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'
],
person Michael Benford    schedule 09.10.2013
comment
Есть ли место, где я могу объявить эту переменную для всех моих тестов, а не файл за файлом? - person Mimo; 09.10.2013
comment
@Maurizio Вы можете просто создать отдельный файл JS, объявить в нем переменную и добавить ее в свой karma.conf.js. - person Michael Benford; 09.10.2013
comment
@MichaelBenford, ваше первое решение мне не подходит. Может ли порядок файлов javascript быть проблемой? Если тестируемый файл ссылается на глобальную переменную, но глобальная переменная определена только в тестовом файле (загруженном ПОСЛЕ), приведет ли это к сбою? - person Mark van Proctor; 30.04.2014
comment
@MarkvanProctor Использует ли тестируемый файл глобальную переменную до того, как будет выполнен ее тестовый аналог? - person Michael Benford; 01.05.2014
comment
Верно. Что было бы здорово, так это объект globals в karma.conf, который регистрируется до загрузки любых файлов javascript. - person Mark van Proctor; 02.05.2014
comment
@MarkvanProctor Вы можете добиться этого, создав файл (например, globals.js), содержащий все ваши глобальные переменные, и добавив его в качестве первой записи в ваш файл karma.conf.js. - person Michael Benford; 03.05.2014
comment
Я вижу здесь одну проблему — параллелизм на тестовых фермах. Если файл может иметь разное содержимое для каждого тестового прогона, но может потребоваться его параллельное выполнение, то это довольно неполный вариант. Так что было бы очень приятно иметь возможность передавать переменные через переменные среды r, что, похоже, невозможно сделать в настоящее время. - person Chris Travers; 22.01.2016
comment
(окно как любое).pageState = 'xyzzy'; - person Paul Lockwood; 11.09.2019
comment
Спасибо за ответы. Вы действительно спасли мой день. Возможно, стоит упомянуть, что если вы меняете karma.conf.js, вам также необходимо перезапустить тесты (остановить текущее выполнение и перезапустить его снова) - person developer; 05.12.2019

Если вы переходите с 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> используется для того, чтобы мы могли без ошибок ссылаться на функцию, потому что она закрытая, иначе мы получим ошибку машинописного текста;

person L1ghtk3ira    schedule 23.11.2018

Первое решение у меня не сработало в 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()
);
person occasl    schedule 18.11.2016
comment
Это сработало для меня, но tslint не может видеть это как переменную. :( - person TiggerToo; 17.07.2017
comment
Использование веб-пакета и кармы должно было явно назначаться окну, иначе возникала строгая ошибка. ReferenceError: Строгий режим запрещает неявное создание глобального свойства ' window.API_URL = 'localhost:8080/api'; - person Jozzhart; 31.05.2018