TypeError:undefined不是构造函数

Ada*_*her 31 javascript phantomjs angularjs karma-jasmine

我对Angular很新,而且我还在努力解决这个问题.我正在使用我从Yeoman Generator生成的Angular 1.5.8编写一些测试.

具体来说,我正在试图弄清楚如何操纵$ 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 = "";
}])
Run Code Online (Sandbox Code Playgroud)

大约一半的线(我添加评论的地方)失败了.具体来说,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
        $broadcast@bower_components/angular/angular.js:18005:33
        bower_components/angular-ui-router/release/angular-ui-router.js:3353:32
        processQueue@bower_components/angular/angular.js:16383:30
        bower_components/angular/angular.js:16399:39
        $eval@bower_components/angular/angular.js:17682:28
        $digest@bower_components/angular/angular.js:17495:36
        $apply@bower_components/angular/angular.js:17790:31
        done@bower_components/angular/angular.js:11831:53
        handleResponse@bower_components/angular-mocks/angular-mocks.js:1368:17
        flush@bower_components/angular-mocks/angular-mocks.js:1808:26
        test/spec/services/breadcrumbservice.js:33:27
        invoke@bower_components/angular/angular.js:4718:24
        workFn@bower_components/angular-mocks/angular-mocks.js:3085:26
Run Code Online (Sandbox Code Playgroud)

这是我的测试代码(从不同的例子中修改了一些垃圾 - 只是试图让它工作):

'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);

    });
});
Run Code Online (Sandbox Code Playgroud)

我不怀疑我在这里做错了什么,我只是不太明白它是什么.这个错误到底意味着什么?为什么它不喜欢我的电话endsWith

谢谢

dgr*_*raf 56

undefined不是构造函数

是您尝试调用未定义的函数时PhantomJS显示的错误消息.这取决于PhantomJS支持的ECMAScript版本.正如您所说,它在Chrome中运行良好,因为此浏览器支持您在测试中使用的功能.为了解决您的问题并且仍然可以使用PhantomJS,您可以用您自己的"未知PhantomJS"功能替换它.

  • 如果它说"你试图调用一个未定义的函数",肯定会更酷 (12认同)

Hul*_*ell 18

TypeError: undefined is not a constructor使用该includes()方法时遇到错误.这些includes()endsWith()方法在ECMAScript 2015中是新的,并且在Internet Explorer中不受支持,显然不是PhantomJS.

您的最终用户可能正在使用Internet Explorer.在这种情况下,您可能希望使用完全支持的indexOf()方法而不是includes()endsWith()

例如,在我的情况下,一切都在chrome中运行良好,但我的测试失败了:

if (item.name.includes('contents'))
Run Code Online (Sandbox Code Playgroud)

我改为使用indexOf()方法代替:

if (item.name.indexOf('contents') !== -1)
Run Code Online (Sandbox Code Playgroud)

然后我不再收到错误

TypeError:undefined不是构造函数


Ada*_*her 10

我辩论是否将此作为答案发布或仅仅是对我的问题进行编辑,但我想这是我的答案(目前):

看来这个问题与PhantomJS有关.只要我在karma.conf.js文件中将引擎更改为Chrome,就会通过这些测试.

我仍然不知道该错误信息应该是什么意思以及为什么它不能与PhantomJS合作,但至少我现在能够继续.

以下是对我的karma.conf.js的修改(如果有人好奇的话):

browsers: [
 //'PhantomJS',
 'Chrome'
],

// Which plugins to enable
plugins: [
 'karma-chrome-launcher',
 //'karma-phantomjs-launcher',
 'karma-jasmine'
],
Run Code Online (Sandbox Code Playgroud)

顺便说一句 - 我确实注意到endsWithECMAScript6是新手(我以为它比较旧),但是WebStorm表明它在angular-ui-grid中引用了一个辅助函数.我花了很files长时间搞乱karma.conf.js文件中的数组,试图看看ui-grid依赖是否加载得太迟或什么的.在每次测试中,它在Chrome中都运行良好但不是PhantomJS.我仍然不知道为什么.


Mar*_*tin 6

在我的情况下:循环依赖导致:

PhantomJS 2.1.1(Windows 8 0.0.0)ERROR TypeError:undefined不是构造函数(在'undefined:'中评估'(0,_actions.prefix)('SET_USER_INPUT_PHONE_NUMBER')')

我在我的javascript生产代码中添加了导入(用babel/webpack编译的ES6语法)后出现了同样的错误.当应用程序的生产版本加载到chrome中但是使用phantomJS运行测试时产生了错误,这些更改很好.在我的例子中,添加的导入创建了循环依赖.

我将此放在这里供将来参考(几周前我偶然发现了同样的问题,并且不想再在几周内再次划伤我的脑袋)以及其他谷歌相同的错误.