我正在尝试使用Node.js对angularjs控制器进行单元测试。我正在使用gulp.js和摩卡通过gulp-mocha来运行测试。
这是我的gulpfile.js
现在的样子:
(function () {
var gulp = require('gulp');
var mocha = require('gulp-mocha');
gulp.task('default', function () {
return gulp
.src('Scripts/Tests/*.js', { read: false })
.pipe(mocha({
ui: 'tdd',
reporter: 'dot',
globals: {
angular: require('./Scripts/angular.js')
}
}));
});
})();
这是正在测试的代码:
(function () {
var application = angular.module('Main');
application.controller('MainController', ['$scope', function ($scope) {
$scope.isDisabled = function () {
return true;
};
}]);
})();
这是测试文件本身:
(function () {
var chai = require('chai');
var assert = chai.assert;
angular.module('Main', []); // Create an empty module
require('../MainController.js'); // Fill the module with the controller
suite('Main Controller', function () {
test('isDisabled always true', function () {
var controllerFactory = angular.injector.get('$controller');
var controller = controllerFactory('MainController', {
'$scope': {}
});
var result = controller.isDisabled();
assert.isTrue(result);
});
});
})();
我需要将角度设置为全局,以便我的测试和我正在测试的文件正常工作。但是,在gulpfile.js
中调用require
给了我一个Reference Error: window is not defined
错误。这是有道理的,因为我在 Node.js 中运行。
我需要做什么才能在 Node.js 中加载角度?
@unobf所说(以及angularjs文档所说(,从Node测试角度的诀窍.js是使用Karma。这意味着通过npm install
安装karma
和karma-mocha
,以及karma-chrome-launcher
,karma-ie-launcher
,karma-firefox-launcher
(或其他任何东西(。
然后我基本上不得不从头开始重做我的gulp.js
文件:
(function () {
var gulp = require('gulp');
var karma = require('karma').server;
gulp.task('runTests', function (done) {
karma.start({
configFile: __dirname + '/karma.config.js',
singleRun: true
}, done);
});
gulp.task('default', ['runTests']);
})();
我还必须创建一个karma.config.js
文件来配置业力以使用Chrome,Firefox,IE和摩卡。在同一个文件中,我将 mocha 配置为使用 tdd UI 和点报告器:
module.exports = function(config) {
config.set({
browsers: ['Chrome', 'Firefox', 'IE'],
frameworks: ['mocha'],
files: [
'./Scripts/angular.js',
'./Scripts/chai.js',
'./Scripts/*.js',
'./Scripts/Tests/*.js'
],
singleRun: true,
client: {
mocha: {
reporter: 'dot',
ui: 'tdd'
}
}
});
};
我了解到您必须首先指定angularjs,chai.js等,以便首先拾取它们并在全局范围内用于其他文件。同样,要测试的代码的文件必须在测试文件之前列出。
正在测试的代码根本没有改变。一旦我的测试开始运行,我意识到我的测试被破坏了,最终看起来像这样通过:
(function () {
var assert = chai.assert;
suite('Main Controller', function () {
test('isDisabled always true', function () {
var injector = angular.injector(['ng', 'Main']);
var $controller = injector.get('$controller');
var scope = {};
var controller = $controller('MainController', {
'$scope': scope
});
var result = scope.isDisabled();
assert.isTrue(result);
});
});
})();
最大的收获是控制器只是填充$scope
对象。我改为在$scope
对象上调用isDisabled()
。当然,获取控制器是一项繁重的工作,因此使用 angular-mocks.js
提供的inject
方法更有意义:
(function () {
var assert = chai.assert;
suite('Main Controller', function () {
var $scope = {};
setup(function () {
module('Main');
inject(function ($controller) {
$controller('MainController', {
'$scope': $scope
});
});
});
test('isDisabled always true', inject(function ($controller) {
var result = $scope.isDisabled();
assert.isTrue(result);
}));
});
})();
希望这足以让任何尝试使用 Node.js 和 mocha 来测试 angularjs 代码的人入门。
我在Grunt中这样做,但同样的原则也适用于Gulp。您需要注入"角度模拟.js"文件才能模拟依赖注入。我正在使用 Karma http://karma-runner.github.io/0.12/index.html 来执行此操作,并在我的 karma.conf.js 文件中设置它,如下所示:
module.exports = function(config){
config.set({
basePath : '../../',
files : [
'bower_components/angular/angular.js',
'bower_components/angular-mocks/angular-mocks.js',
...
然后,您可以将$controller注入到测试中,并执行诸如测试控制器初始化之类的操作。下面的测试是初始化范围,然后测试控制器是否正在向范围添加方法(注意,我使用的是 Jasmine,但摩卡也可以这样做(,但 Jasmine 带有一些不错的内置间谍功能。
describe('analysisController', function () {
var scope, state;
beforeEach(function () {
module('analysis');
scope = {
$apply:jasmine.createSpy(),
ws: {
registerCallback:jasmine.createSpy(),
sendMessage:jasmine.createSpy()
}
},
state = {
go : jasmine.createSpy()
};
});
it('should add a bunch of methods to the scope', inject(function ($controller) {
$controller('analysisController', {
$scope : scope,
$state: state
});
expect(typeof scope.colorContrast).toBe('function');
expect(typeof scope.XPathFromIssue).toBe('function');
}));
...