Модульное тестирование в AngularJS с жасмином и наглостью
Я пытаюсь написать модульные тесты для существующего проекта SPA, построенного на angularJS. Я получаю ошибку "Не могу найти переменную: модуль" всякий раз, когда пытаюсь выполнить код.
Я установил библиотеки с помощью npm.
Для этого я использовал библиотеки Chutzpah и Jasmine.
appModule.js
(function () {
'use strict';
angular.module('app', [
'ngMessages',
'ui.router',
'ui.router.title'
]).run(['REQ_TOKEN', function (REQ_TOKEN) {
//...
}]).config(['$httpProvider', function ($httpProvider) {
$httpProvider.defaults.headers.common["X-Requested-With"] = 'XMLHttpRequest';
}]);
})();
site.js
(function () {
'use strict';
window.deferredBootstrapper.bootstrap({
element: window.document,
module: 'app',
resolve: {
REQ_TOKEN: ['$http', function ($http) {
return $http.get('/.../', { ignoreLoadingBar: true, params: { ts: new Date().getTime() } });
}]
}
});
})();
appController.js:
(function () {
'use strict';
angular
.module('app')
.controller('appController', appController);
appController.$inject = ['apiServices', '$scope'];
function appController(apiServices, $scope) {
$scope.value = 5;
}
})();
apiServices.js
(function () {
'use strict';
angular
.module('app')
.factory('apiServices', apiServices);
apiServices.$inject = ['$http', '$log', '$q'];
function apiServices($http, $log, $q) {
var clientServicesPath = '/api/ClientServices',
service =
{ ....... };
return service;
}
})();
appControllerSpec.js
/// <reference path="../../../lib/angular/angular.js" />
/// <reference path="../../../lib/angular-deferred-bootstrap/angular-deferred-bootstrap.js" />
/// <reference path="../../../lib/angular-ui-router/release/angular-ui-router.js" />
/// <reference path="../../../lib/angular-ui-router-title/angular-ui-router-title.js" />
/// <reference path="../../../lib/angular-messages/angular-messages.js" />
/// <reference path="../../modules/appmodule.js" />
/// <reference path="../../site.js" />
/// <reference path="../../factories/sharedfunctions.js" />
/// <reference path="../../services/apiservices.js" />
/// <reference path="../../controllers/appcontroller.js" />
/// <reference path="../../../../node_modules/jasmine/bin/jasmine.js" />
/// <reference path="../../../../node_modules/jasmine/lib/jasmine.js" />
/// <reference path="../../../../node_modules/jasmine-ajax/lib/mock-ajax.js" />
/// <reference path="../../../lib/angular-mocks/angular-mocks.js" />
describe('When using appController ', function () {
//initialize Angular
beforeEach(module('app'));
var ctrl, scope, apiServices;
beforeEach(inject(function ($injector) {
apiServices = $injector.get('apiServices');
}));
beforeEach(inject(function ($controller, $rootScope, apiServices) {
scope = $rootScope.$new();
var ctrl = $controller('appController', { $scope: scope, apiServices: apiServices });
}));
it('initial value is 5', function () {
expect(scope.value).toBe(5);
});
});
Я получаю следующую ошибку:
Проверка "При использовании appController: начальное значение 5" не удалась Ошибка: [$injector:unpr] Неизвестный поставщик: REQ_TOKENProvider <- REQ_TOKEN http://errors.angularjs.org/1.5.1/$ injector / unpr? P0=REQ_TOKENProvider%20%3C-%20REQ_TOKEN в файле:///C:/Users/Bhanu/......./lib/angular/angular.js (строка 4418) в getService (файл: /// C: / Users) /Bhanu/......./lib/angular/angular.js:4571:46) в файле:///C:/Users/Bhanu/......./lib/angular/angular.js:4423:48 в getService (файл:///C:/Users/Bhanu/......./lib/angular/angular.js:4571:46) в jectionArgs (файл:///C:/Users/Bhanu/......./lib/angular/angular.js:4595:68) при вызове (файл:///C:/Users/Bhanu/......./lib/angular/angular.js:4617:31) Ошибка: [$ инжектор: unpr] Неизвестный поставщик: REQ_TOKENProvider <- REQ_TOKEN http://errors.angularjs.org/1.5.1/$ injector / unpr? p0=REQ_TOKENProvider%20%3C-%20REQ_TOKEN в файле:///C:/Users/Bhanu/......./lib/angular/angular.js (строка 4418) в getService (файл: /// C: / Users / Bhanu /......./lib/angular/angular.js:4571:46) в файле: /// C: / Users / Bha nu /......./ lib / angular / angular.js: 4423: 48 в getService (файл: /// C: /Users/Bhanu/......./lib/angular/angular. js: 4571: 46) в jectionArgs (файл: /// C: /Users/Bhanu/......./lib/angular/angular.js: 4595: 68) при вызове (файл: /// C: / Users / Bhanu /......./ lib / angular / angular.js: 4617: 31) в C:\Users\Bhanu.......\js\TestingJS\controllers\appControllerSpec.js (строка 43)
0 пройдено, 1 не пройдено, 1 всего (наглость).
Я перепробовал все возможные решения, но ни одно из них не помогло мне. Я выполнил тесты напрямую, щелкнув правой кнопкой мыши файл контроллера тестирования и выбрав опцию "Запускать тесты JS".
Я чувствую, что есть больше деталей для конфигурации. Пожалуйста, помогите мне с этим.
2 ответа
Это не тот способ, которым вы передаете свои услуги контроллера тестам, а вы создаете новый var ctrl
Переменная в forEach. Кроме того, существует один экземпляр инжектора для каждого приложения. Вы должны получить свой контроллер и ваш экземпляр службы с тем же inject(...)
Неправильно
var ctrl = $controller('appController', { $scope: scope, apiServices: apiServices });
Правильно
describe('When using appController ', function () {
var ctrl, scope, apiServices;
beforeEach(inject(function ($controller, $rootScope) {
// Put it here for the sake of organization
//initialize Angular
module('app');
scope = $rootScope.$new();
// Get controller instance
ctrl = $controller('appController');
// Get service instance
apiServices = $injector.get('apiServices');
}));
it('initial value is 5', function () {
expect(scope.value).toBe(5);
});
});
Согласно документации по deferredBootstrapper,
Поскольку константы, которые deferredBootstrapper добавляет к вашему модулю приложений, недоступны в ваших модульных тестах, имеет смысл предоставить их в глобальном beforeEach():
Итак, appControllerSpec.js должен быть
/// <reference path="../../../lib/angular/angular.js" />
/// <reference path="../../../lib/angular-deferred-bootstrap/angular-deferred-bootstrap.js" />
/// <reference path="../../../lib/angular-ui-router/release/angular-ui-router.js" />
/// <reference path="../../../lib/angular-ui-router-title/angular-ui-router-title.js" />
/// <reference path="../../../lib/angular-messages/angular-messages.js" />
/// <reference path="../../modules/appmodule.js" />
/// <reference path="../../site.js" />
/// <reference path="../../factories/sharedfunctions.js" />
/// <reference path="../../services/apiservices.js" />
/// <reference path="../../controllers/appcontroller.js" />
/// <reference path="../../../../node_modules/jasmine/bin/jasmine.js" />
/// <reference path="../../../../node_modules/jasmine/lib/jasmine.js" />
/// <reference path="../../../../node_modules/jasmine-ajax/lib/mock-ajax.js" />
/// <reference path="../../../lib/angular-mocks/angular-mocks.js" />
describe('When using appController ', function () {
//initialize Angular
beforeEach(module('app'));
var ctrl, scope, apiServices, REQ_TOKEN;
beforeEach(function () {
module(function ($provide) {
$provide.constant('REQ_TOKEN', { token: '/dummyValue' });
});
});
beforeEach(inject(function ($controller, $rootScope, apiServices) {
scope = $rootScope.$new();
REQ_TOKEN = $injector.get('REQ_TOKEN');
apiServices = $injector.get('apiServices');
var ctrl = $controller('appController', { $scope: scope});
}));
it('initial value is 5', function () {
expect(scope.value).toBe(5);
});
});