2016-08-13 195 views
16

我对Angular非常陌生,而且我正在尝试着将其中的大部分内容都解决。我正在使用从Yeoman Generator生成的Angular 1.5.8编写一些测试。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不是构造函数”是一条错误消息PhantomJS在尝试调用未定义的函数时显示。它取决于PhantomJS支持的ECMAScript版本。正如你所说的,它在Chrome中运行良好,因为该浏览器支持您在测试中使用的功能。 为了解决您的问题,仍然可以使用PhantomJS,您可以用您自己的“PhantomJS”功能替换“未知的PhantomJS”功能。

8

我辩论是否要发布此为答案或只是一个编辑我的问题,但我想这是我的答案(现在):

看来问题是关系到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' 
], 

顺便说一句 - 我注意到endsWith是新ECMAScript6(我想这是长辈)但是WebStorm显示它在angular-ui-grid中引用了一个辅助函数。我在karma.conf.js文件中花费了很长时间处理files数组,以试图查看ui-grid依赖项是否加载得太晚或某事。在每次测试中,Chrome都能正常工作,但不是PhantomJS。我仍然不知道为什么。

+0

我与PhantomJS有类似的问题。大多数情况下,所有的测试都通过了,但是其他时候它们都会失败,出现同样的错误“TypeError:undefined不是一个构造函数(正在评估...”),只发生在Windows上的PhantomJS中,使用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

我得到了同样的错误后,我在我的JavaScript生产代码(ES6语法与巴贝尔/编译的WebPack)增加进口。 当应用程序的生产版本被加载到chrome中时,所做的更改没有问题,但使用phantomJS运行测试会产生错误。 在我的情况下,添加的导入创建了循环依赖关系。

我把这里放在这里供将来参考(我几周前偶然发现了同样的问题,并且不想再在几个星期内再次挠挠我的头)以及其他谷歌同样的错误。

+0

I'在运行单元测试时也得到这个错误,并怀疑它在工作时也是循环模块依赖。感谢您的发帖。 –

+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 错误

相关问题