【发布时间】:2016-01-26 16:02:15
【问题描述】:
我目前正在尝试为 Angular 应用程序中的控制器编写业力单元测试。对我来说,想要的结果是只加载我正在测试的控制器(假设现在我只想测试这个控制器)并为我模拟所有其他依赖项。
搭建舞台:
- 我有一个模块:'XYZ' 定义在
js/xyz_module.js - 我有一个模块:'ABC' 定义在
js/abc_module.js - 模块“ABC”依赖于“XYZ”
- 模块'ABC'有一个控制器:'AbcController'定义在
js/abc_controller.js - 我的测试只能在“AbcController”上进行
karma.conf.js:
module.exports = function(config) {
config.set({
basePath: '',
frameworks: ['jasmine'],
files: [
'node_modules/angular/angular.js',
'node_modules/angular-mocks/angular-mocks.js',
'js/abc_module.js',
'js/controllers/abc_controller.js',
'spec/karma/abc_controller_spec.js'
],
...
abc_module.js:
angular.module('ABC', ['XYZ']);
abc_controller.js:
angular.module('ABC').controller('AbcController', ['$scope', function($scope) {
$scope.letters = ['a', 'b', 'c']
}]);
abc_controller_spec.js:
describe('AbcController', function() {
beforeEach(function() {
angular.mock.module('XYZ');
module('ABC')
});
var $controller;
beforeEach(inject(function(_$controller_) {
$controller = _$controller_
}));
describe('$scope.letters', function() {
it("is set to three letters", function() {
var $scope = {};
$controller('AbcController', {$scope: $scope});
expect($scope.letters.length).toEqual(3)
})
})
});
我的理论是,因为模块 XYZ 是一个模拟模块,我不应该在我的 karam.conf.js 文件中包含 js/xyz_module.js,但模拟框架会简单地为我模拟它。不幸的是,情况似乎并非如此。当我运行 karma 时,我收到一个错误,它找不到模块“XYZ”。有没有办法解决?如果我必须包含所有依赖项,甚至测试应用程序的一部分,这将使更复杂的应用程序变得更加困难。显然,这是一个人为的例子,而我实际使用的项目涉及许多具有许多依赖关系的模块,如果我必须有效地包含整个应用程序,那么测试它的一部分就变得非常困难。我以为这就是嘲讽的全部意义?我错过了什么吗?
【问题讨论】:
-
无法完全理解需求。所以你想在 karma 运行时只测试一个控制器而不是所有文件?
-
我希望能够测试模块而不必包含所有依赖项。我想模拟(也许存根是一个更好的术语)依赖项,特别是当被测试的代码中没有使用依赖项时。
-
beforeEach(angular.mock.module('XYZ', []));?或者this 是您要找的? -
听起来不错,如果它有效的话!最初我希望这样做可以解决问题,但是当我添加: beforeEach(angular.mock.module('XYZ', []));我仍然收到错误:无法实例化模块 XYZ,原因是:模块 'XYZ' 不可用!这听起来像是在尝试加载一个实际的模块,而不是一个模拟。
标签: javascript angularjs unit-testing karma-runner