I'm very new to Angular and I'm trying to figure much of this out still. I'm writing some tests using Angular 1.5.8 which I generated from the Yeoman Generator.
Specifically, I'm trying to figure out how to manipulate $httpBackend results (I'm not sure if that's important or not)...
In my app.js file I have the following code:
.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 = "";
}])
The line about halfway down (where I added the comment) is failing. Specifically, the endsWith
function is failing (toLower is fine), with this error:
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
Here is my test code (some junk modified from different examples - just trying to get it to work):
'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);
});
});
I don't doubt that I'm doing something wrong here, I just can't quite understand what it is. What does this error really mean and why does it not like my call to endsWith
?
Thanks
undefined is not a constructor
is an error message PhantomJS displays when you tried to call a function that is not defined. It depends on the version of ECMAScript which your PhantomJS supports. So as you said it works fine in Chrome, because this browser supports the function you are using in test. In order to fix your problem and still be able to use PhantomJS you can replace the "unknown to PhantomJS" function with your own.