2016-08-13 2 views
16

Я очень новичок в Angular, и я пытаюсь понять, что из этого все равно. Я пишу некоторые тесты, используя Angular 1.5.8, которые я создал из Yeoman Generator.TypeError: undefined не является конструктором

В частности, я пытаюсь понять, как манипулировать $ 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's 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?

Благодаря

ответ

30

«undefined is not a constructor» является сообщением об ошибке PhantomJS, когда вы пытаетесь вызвать функцию, которая не определена. Это зависит от версии ECMAScript, которую поддерживает ваш PhantomJS. Итак, как вы сказали, он отлично работает в Chrome, потому что этот браузер поддерживает функцию, которую вы используете в тесте. Чтобы исправить вашу проблему и по-прежнему использовать PhantomJS, вы можете заменить функцию «неизвестно на PhantomJS» своим собственным.

8

я обсуждал ли не размещать это как ответ или просто редактировать на мой вопрос, но я предполагаю, что это мой ответ (на данный момент):

Похоже, проблема связана с 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 показывает, что он ссылается на вспомогательную функцию в угловой-ui-сетке. Я потратил довольно много времени на беспорядок с массивом files в файле karma.conf.js, пытаясь выяснить, загружается ли зависимость ui-grid слишком поздно или что-то в этом роде. В каждом тесте он отлично работал в Chrome, но не PhantomJS. Я до сих пор не знаю, почему.

+0

У меня есть аналогичные проблемы с PhantomJS. В большинстве случаев все тесты проходят, но в других случаях все они терпят неудачу с той же ошибкой «TypeError: undefined не является конструктором (оценка ...). Только происходит с PhantomJS в Windows. Использование Chrome ошибок никогда не происходит. –

4

В моем случае: Циклические зависимости Причинения:

PhantomJS 2.1.1 (Windows 8 0.0.0) ERROR TypeError: undefined is not a constructor (evaluating '(0, _actions.prefix)('SET_USER_INPUT_PHONE_NUMBER')') at undefined:12

Я получил ту же ошибку после того, как я добавил импорт в моем яваскрипте коды производства (ES6 синтаксисе скомпилирован с столпотворением/WebPack). Изменения были прекрасны, когда производственная сборка приложения была загружена в хром, но запуск тестов с помощью phantomJS вызвал ошибку. В моем случае добавленный импорт создал циклические зависимости.

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

+0

I ' m получать эту ошибку, а также при запуске модульного теста и подозревать, что он также связан с циклическим модулем. Спасибо за сообщение. –

+0

Добро пожаловать. Я рад, что это помогает и другим, и не только мне. – Martin

2

Я получаю TypeError: undefined is not a constructor с помощью метода includes(). Методы includes() и endsWith() являются новыми в ECMAScript 2015 и не поддерживаются в Internet Explorer и, очевидно, не PhantomJS.

Существует вероятность, что ваш конечный пользователь может использовать Internet Explorer. В этом случае, вы можете использовать полностью поддерживаемый indexOf() метод вместо includes() или endsWith()

К примеру, в моем случае, все прекрасно работало в хроме, но мои тесты потерпели неудачу на линии:

if (item.name.includes('contents'))

Я изменен с помощью метода IndexOf() вместо того, чтобы:

if (item.name.indexOf('contents') !== -1)

И тогда я уже не получаю TypeError: undefined is not a constructor Ошибка