我对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 = "";
}])
大约一半的线(我添加评论的地方)失败了。具体来说,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
这是我的测试代码(从不同的示例中修改了一些垃圾 - 只是试图让它工作):
'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
的呼吁?
由于
答案 0 :(得分:53)
undefined不是构造函数
是当您尝试调用未定义的函数时PhantomJS显示的错误消息。这取决于PhantomJS支持的ECMAScript版本。正如您所说,它在Chrome中运行良好,因为此浏览器支持您在测试中使用的功能。 为了解决您的问题并且仍然可以使用PhantomJS,您可以替换PhantomJS"与你自己的功能。
答案 1 :(得分:13)
我使用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'))
我改为使用indexOf()方法:
if (item.name.indexOf('contents') !== -1)
然后我不再收到错误
TypeError:undefined不是构造函数
答案 2 :(得分: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'
],
顺便说一句 - 我注意到endsWith
是ECMAScript6的新手(我以为它比较旧),但是WebStorm表明它在angular-ui-grid中引用了一个辅助函数。我花了很长时间搞乱karma.conf.js文件中的files
数组,试图查看ui-grid依赖项是否加载太晚或者什么。在每次测试中,它在Chrome中都运行良好但不是PhantomJS。我仍然不知道为什么。
答案 3 :(得分:6)
在我的案例中:循环依赖性导致:
PhantomJS 2.1.1(Windows 8 0.0.0)错误TypeError:undefined不是构造函数(评估'(0,_actions.prefix)('SET_USER_INPUT_PHONE_NUMBER')')未定义:12
在我的javascript生成代码中添加导入(用babel / webpack编译的ES6语法)后,我得到了同样的错误。 当应用程序的生产版本加载到chrome中但是使用phantomJS运行测试时产生了错误,这些更改很好。 在我的例子中,添加的导入创建了循环依赖。
我将此放在此处以备将来参考(几周前我偶然发现了同样的问题,并且不想再在几周内再次抓挠我的脑袋)以及其他谷歌出现同样错误的人。
答案 4 :(得分:0)
我在使用PhantomJS时遇到类似的错误:
对我来说,错误是我为服务创建间谍对象的方式。
代码文件new Service.getData(param1, param2)
中的在线错误
修正测试文件:jasmine.createSpyObj('Service',['getData'])
缺少的是在创建spyObj时添加['getData]