Angular,基本测试无效
Angular, basic test not working
控制器:
angular.module('ngApp', [
'templates-app',
'templates-common',
'ngApp.home',
'ui.router'
])
.config(function myAppConfig($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/home');
})
.run(function run() {})
.controller('AppCtrl', function AppCtrl($scope) {
$scope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState, fromParams) {
if (angular.isDefined(toState.data.pageTitle)) {
$scope.pageTitle = toState.data.pageTitle + ' | App';
}
});
});
测试:
describe('AppCtrl', function() {
beforeEach(module('ngApp'));
var $controller;
beforeEach(inject(function(_$controller_) {
$controller = _$controller_;
}));
describe('$scope.pageTitle', function() {
it('should set pageTitle', inject(function() {
var $scope = {};
var AppCtrl = $controller('AppCtrl', { $scope: $scope });
expect(true).toBe(true);
}));
});
});
我现在没有测试任何东西,只是加载控制器。然而这失败了
Chrome 41.0.2272 (Mac OS X 10.10.2) AppCtrl $scope.pageTitle should set pageTitle FAILED
TypeError: undefined is not a function
at new AppCtrl (/src/app/app.js:15:9)
at invoke (/vendor/angular/angular.js:4203:17)
at Object.instantiate (/vendor/angular/angular.js:4211:27)
at /vendor/angular/angular.js:8501:28
at /vendor/angular-mocks/angular-mocks.js:1878:12
at Object.<anonymous> (/src/app/app.spec.js:14:19)
at Object.invoke (/vendor/angular/angular.js:4203:17)
at Object.workFn (/vendor/angular-mocks/angular-mocks.js:2436:20)
Error: Declaration Location
at window.inject.angular.mock.inject (/vendor/angular-mocks/angular-mocks.js:2407:25)
at Suite.<anonymous> (/src/app/app.spec.js:12:30)
at Suite.<anonymous> (/src/app/app.spec.js:11:2)
at /src/app/app.spec.js:1:1
我的测试设置有什么问题吗?
实测:
describe('$scope.pageTitle', function() {
it('should be defiend after stateChange', inject(function() {
var $scope = {};
var AppCtrl = createController('AppCtrl');
scope.$broadcast('$stateChangeSuccess', {
data: {
pageTitle: 'bar'
}
});
expect(scope.pageTitle).toBeDefined();
}));
});
我认为问题在于您注入控制器的范围和 $scope.$on... 。试试这个:
describe('AppCtrl', function() {
beforeEach(module('ngApp'));
var $controller, $scope;
beforeEach(inject(function(_$controller_, _$rootScope_) {
$controller = _$controller_;
$rootScope = _$rootScope_.$new();
}));
describe('$scope.pageTitle', function() {
it('should set pageTitle', inject(function() {
var AppCtrl = $controller('AppCtrl', { $scope: $scope });
expect(true).toBe(true);
}));
});
});
您需要从 $rootScope
创建范围并注入它:
beforeEach(inject(function (_$controller_, $rootScope) {
$controller = _$controller_;
scope = $rootScope.$new();
createController = function (ctrlName) {
return $controller(ctrlName, {
'$scope': scope
});
};
}));
通过这种方式,您可以使用 createController
功能,并使用:
var AppCtrl = createController('AppCtrl');
因为有控制器。
这是一个有效的 jsfiddle:
http://jsfiddle.net/Lbs6sk0k/2/
编辑:$scope
哪里是空的?
如果我在这里放一个 console.log
:
.controller('AppCtrl', function AppCtrl($scope) {
console.log($scope);
我可以看到这个:
编辑 2:
将范围设置为全局变量:
describe('AppCtrl', function () {
beforeEach(module('ngApp'));
var $controller;
var scope;
然后,在你的测试用例中,你可以使用它:
it('should set pageTitle', inject(function () {
var $scope = scope;
用你的新测试用例更新了 jsfiddle:http://jsfiddle.net/Lbs6sk0k/3/
控制器:
angular.module('ngApp', [
'templates-app',
'templates-common',
'ngApp.home',
'ui.router'
])
.config(function myAppConfig($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/home');
})
.run(function run() {})
.controller('AppCtrl', function AppCtrl($scope) {
$scope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState, fromParams) {
if (angular.isDefined(toState.data.pageTitle)) {
$scope.pageTitle = toState.data.pageTitle + ' | App';
}
});
});
测试:
describe('AppCtrl', function() {
beforeEach(module('ngApp'));
var $controller;
beforeEach(inject(function(_$controller_) {
$controller = _$controller_;
}));
describe('$scope.pageTitle', function() {
it('should set pageTitle', inject(function() {
var $scope = {};
var AppCtrl = $controller('AppCtrl', { $scope: $scope });
expect(true).toBe(true);
}));
});
});
我现在没有测试任何东西,只是加载控制器。然而这失败了
Chrome 41.0.2272 (Mac OS X 10.10.2) AppCtrl $scope.pageTitle should set pageTitle FAILED
TypeError: undefined is not a function
at new AppCtrl (/src/app/app.js:15:9)
at invoke (/vendor/angular/angular.js:4203:17)
at Object.instantiate (/vendor/angular/angular.js:4211:27)
at /vendor/angular/angular.js:8501:28
at /vendor/angular-mocks/angular-mocks.js:1878:12
at Object.<anonymous> (/src/app/app.spec.js:14:19)
at Object.invoke (/vendor/angular/angular.js:4203:17)
at Object.workFn (/vendor/angular-mocks/angular-mocks.js:2436:20)
Error: Declaration Location
at window.inject.angular.mock.inject (/vendor/angular-mocks/angular-mocks.js:2407:25)
at Suite.<anonymous> (/src/app/app.spec.js:12:30)
at Suite.<anonymous> (/src/app/app.spec.js:11:2)
at /src/app/app.spec.js:1:1
我的测试设置有什么问题吗?
实测:
describe('$scope.pageTitle', function() {
it('should be defiend after stateChange', inject(function() {
var $scope = {};
var AppCtrl = createController('AppCtrl');
scope.$broadcast('$stateChangeSuccess', {
data: {
pageTitle: 'bar'
}
});
expect(scope.pageTitle).toBeDefined();
}));
});
我认为问题在于您注入控制器的范围和 $scope.$on... 。试试这个:
describe('AppCtrl', function() {
beforeEach(module('ngApp'));
var $controller, $scope;
beforeEach(inject(function(_$controller_, _$rootScope_) {
$controller = _$controller_;
$rootScope = _$rootScope_.$new();
}));
describe('$scope.pageTitle', function() {
it('should set pageTitle', inject(function() {
var AppCtrl = $controller('AppCtrl', { $scope: $scope });
expect(true).toBe(true);
}));
});
});
您需要从 $rootScope
创建范围并注入它:
beforeEach(inject(function (_$controller_, $rootScope) {
$controller = _$controller_;
scope = $rootScope.$new();
createController = function (ctrlName) {
return $controller(ctrlName, {
'$scope': scope
});
};
}));
通过这种方式,您可以使用 createController
功能,并使用:
var AppCtrl = createController('AppCtrl');
因为有控制器。
这是一个有效的 jsfiddle: http://jsfiddle.net/Lbs6sk0k/2/
编辑:$scope
哪里是空的?
如果我在这里放一个 console.log
:
.controller('AppCtrl', function AppCtrl($scope) {
console.log($scope);
我可以看到这个:
编辑 2:
将范围设置为全局变量:
describe('AppCtrl', function () {
beforeEach(module('ngApp'));
var $controller;
var scope;
然后,在你的测试用例中,你可以使用它:
it('should set pageTitle', inject(function () {
var $scope = scope;
用你的新测试用例更新了 jsfiddle:http://jsfiddle.net/Lbs6sk0k/3/