TypeError: undefined не является конструктором
Я очень новичок в Angular, и я все еще пытаюсь понять многое из этого. Я пишу несколько тестов, используя Angular 1.5.8, которые я создал из генератора Yeoman.
В частности, я пытаюсь понять, как манипулировать результатами $httpBackend (я не уверен, что это важно или нет)...
В моем файле app.js у меня есть следующий код:
.run(['$rootScope', '$location', 'breadcrumbService', function ($rootScope, $location, breadcrumbService) {
$rootScope.$on('$viewContentLoaded', function () {
jQuery('html, body').animate({scrollTop: 0}, 200);
});
$rootScope.isEditMode = false;
$rootScope.$on('$stateChangeSuccess', function () {
// ------------ this next line is failing -----------
$rootScope.isEditMode = $location.path().toLowerCase().endsWith('/edit') || $location.path().toLowerCase().endsWith('/new');
});
$rootScope.parseJson = function (value) {
return angular.fromJson(value);
};
$rootScope.bc = breadcrumbService;
$rootScope.title = "";
}])
Линия, расположенная на полпути вниз (где я добавил комментарий), терпит неудачу. В частности, функция endsWith
терпит неудачу (toLower в порядке), с этой ошибкой:
PhantomJS 2.1.1 (Windows 8 0.0.0) Service: breadcrumbService should return breadcrumb label in json format FAILED
TypeError: undefined is not a constructor (evaluating '$location.path().toLowerCase().endsWith('/edit')') in app/scripts/app.js (line 44)
app/scripts/app.js:44:72
[email protected]_components/angular/angular.js:18005:33
bower_components/angular-ui-router/release/angular-ui-router.js:3353:32
[email protected]_components/angular/angular.js:16383:30
bower_components/angular/angular.js:16399:39
[email protected]_components/angular/angular.js:17682:28
[email protected]_components/angular/angular.js:17495:36
[email protected]_components/angular/angular.js:17790:31
[email protected]_components/angular/angular.js:11831:53
[email protected]_components/angular-mocks/angular-mocks.js:1368:17
[email protected]_components/angular-mocks/angular-mocks.js:1808:26
test/spec/services/breadcrumbservice.js:33:27
[email protected]_components/angular/angular.js:4718:24
[email protected]_components/angular-mocks/angular-mocks.js:3085:26
Вот мой тестовый код (какой-то мусор, измененный из разных примеров - просто попытка заставить его работать):
'use strict';
describe('Service: breadcrumbService', function () {
// load the service module
beforeEach(module('myModule'));
var $httpBackend, $rootScope, createController, authRequestHandler;
beforeEach(inject(function($injector) {
$httpBackend = $injector.get('$httpBackend');
console.log('Is null? '+ ($httpBackend == null));
$httpBackend.whenGET(/views\/.*/).respond(200, [{}, {}, {}]);
authRequestHandler = $httpBackend.when('GET', '/api/v1/SiteStagings')
.respond({userId: 'userX'}, {'A-Token': 'xxx'});
// Get hold of a scope (i.e. the root scope)
$rootScope = $injector.get('$rootScope');
$httpBackend.flush();
}));
// instantiate service
var breadcrumbService;
beforeEach(inject(function (_breadcrumbService_) {
breadcrumbService = _breadcrumbService_;
}));
it('svc should exist', function () {
expect(!!breadcrumbService).toBe(true);
});
it('should return breadcrumb label in json format', function () {
var result = breadcrumbService.getFromCache('site', 'SiteGroupStagings', 46, 'SiteGroupDesc');
console.log(result);
expect(!!result).toBe(true);
});
});
Я не сомневаюсь, что я делаю что-то неправильно здесь, я просто не могу понять, что это такое. Что действительно означает эта ошибка, и почему мне не нравится мой вызов endsWith
?
Спасибо
Ответы
Ответ 1
undefined не является конструктором
это сообщение об ошибке PhantomJS, когда вы пытались вызвать функцию, которая не определена. Это зависит от версии ECMAScript, которую поддерживает ваш PhantomJS. Итак, как вы сказали, он отлично работает в Chrome, потому что этот браузер поддерживает функцию, которую вы используете в тесте. Чтобы исправить вашу проблему и по-прежнему использовать PhantomJS, вы можете заменить функцию "unknown to PhantomJS" своим собственным.
Ответ 2
Я обсуждал вопрос о том, следует ли публиковать это как ответ или просто изменить мой вопрос, но я думаю, это мой ответ (на данный момент):
Кажется, проблема связана с PhantomJS. Как только я сменил движок на Chrome в файле karma.conf.js, эти тесты прошли.
Я до сих пор не знаю, что такое сообщение об ошибке должно означать и почему оно не работает с PhantomJS, но по крайней мере теперь я могу продолжить.
Вот модификации моего karma.conf.js(в случае, если кому-то интересно):
browsers: [
//'PhantomJS',
'Chrome'
],
// Which plugins to enable
plugins: [
'karma-chrome-launcher',
//'karma-phantomjs-launcher',
'karma-jasmine'
],
Btw - я заметил, что endsWith
является новым для ECMAScript6 (я думал, что он старше), но WebStorm показывает, что он ссылается на вспомогательную функцию в angular -ui-grid. Я потратил довольно много времени на беспорядок с массивом files
в файле karma.conf.js, пытаясь выяснить, загружается ли зависимость ui-grid слишком поздно или что-то в этом роде. В каждом тесте он отлично работал в Chrome, но не PhantomJS. Я до сих пор не знаю, почему.
Ответ 3
Я получаю TypeError: undefined is not a constructor
ошибкой TypeError: undefined is not a constructor
используя метод includes()
. Методы includes()
и endsWith()
новы в ECMAScript 2015 и не поддерживаются в Internet Explorer и, очевидно, не PhantomJS.
Возможно, ваш конечный пользователь может использовать Internet Explorer. В этом случае, вы можете использовать полностью поддерживаемый indexOf()
метод вместо includes()
в endsWith()
includes()
или endsWith()
Например, в моем случае все отлично работало в хроме, но мои тесты не срабатывали на линии:
if (item.name.includes('contents'))
Вместо этого я изменил использование метода indexOf():
if (item.name.indexOf('contents') !== -1)
И тогда я больше не получал ошибку
TypeError: undefined не является конструктором
Ответ 4
В моем случае: Циклические зависимости:
PhantomJS 2.1.1 (Windows 8 0.0.0) ERROR TypeError: undefined не является конструктором (оценка '(0, _actions.prefix) (' SET_USER_INPUT_PHONE_NUMBER ')') в undefined: 12
Я получил ту же ошибку после добавления импорта в код генерации javascript (синтаксис ES6, скомпилированный с помощью babel/webpack).
Изменения были прекрасны, когда сборка приложения была загружена в хром, но запуск тестов с помощью phantomJS вызвал ошибку.
В моем случае добавленный импорт создал циклические зависимости.
Я отбрасываю это здесь для будущей справки (я наткнулся на ту же проблему несколько недель назад и не хочу снова царапать себе голову через пару недель), а для других - ту же ошибку Google.