使用 karma 进行单元测试的注入问题 angularjs
injections issues in unit testing using karma angularjs
我需要通过大量注入(服务、工厂、值)来测试控制器,现在我遇到了一个值问题...
我有以下情况:
这是我的控制器。
(function () {
'use strict';
angular
.module('otpConfigureDatasets')
.controller('otpConfigureDatasetsController', otpConfigureDatasetsController);
otpConfigureDatasetsController.$inject = ['$location', '$state', 'otpWebMapApp', 'otpWMDeltaTracker', 'otpWMStateCache', '$scope', '$timeout', 'otpConfigureDatasetService', 'otpAllDatasetsService', 'otpReviewListDatasetsService','otpConfigureDatasetSelectedTab'];
function otpConfigureDatasetsController($location, $state, otpWebMapApp, otpWMDeltaTracker, otpWMStateCache, $scope, $timeout, otpConfigureDatasetService, otpAllDatasetsService, otpReviewListDatasetsService, otpConfigureDatasetSelectedTab) {
var vm = this;
...
vm.tabs = [{
title: 'MY REVIEW LIST',
selectedAmt: vm.reviewData,
contentTemplate: './app/features/configureDatasets/reviewListDatasets.html',
active: otpConfigureDatasetSelectedTab.tab == 'MyReviewList'
}, {
title: 'ALL DATASETS',
selectedAmt: vm.allData,
contentTemplate: './app/features/configureDatasets/allDatasets.html',
active: otpConfigureDatasetSelectedTab.tab == 'AllDatasets'
}];
...
}
})();
下面是我的Spec.js
'use strict';
describe('Test', function () {
var MainCtrl, scope, _otpWebMapApp_, _otpWMDeltaTracker_, _otpWMStateCache_, _otpConfigureDatasetService_,
_otpAllDatasetsService_, _otpReviewListDatasetsService_, _otpConfigureDatasetSelectedTab_;
beforeEach(function () {
module('otpConfigureDatasets');
});
beforeEach(inject(function ($controller, $rootScope) {
scope = $rootScope.$new();
MainCtrl = $controller('otpConfigureDatasetsController', {
$scope: scope, otpWebMapApp: _otpWebMapApp_, otpWMDeltaTracker: _otpWMDeltaTracker_, otpWMStateCache: _otpWMStateCache_,
otpConfigureDatasetService: _otpConfigureDatasetService_, otpAllDatasetsService: _otpAllDatasetsService_,
otpReviewListDatasetsService: _otpReviewListDatasetsService_, otpConfigureDatasetSelectedTab: _otpConfigureDatasetSelectedTab_
});
}));
it('Should be true', function () {
expect(true).toBe(true);
});
});
但是当我尝试 运行 测试用例时,它不起作用并显示以下错误:
INFO [karma]: Karma v0.12.37 server started at http://localhost:9876/
INFO [launcher]: Starting browser PhantomJS
INFO [PhantomJS 1.9.8 (Windows 8 0.0.0)]: Connected on socket NHknSeC3p_h_lf12SK Gh with id 27552356
PhantomJS 1.9.8 (Windows 8 0.0.0) Test Should be true FAILED
TypeError: 'undefined' is not an object (evaluating 'otpConfigureDatasetSelectedTab.tab')
at otpConfigureDatasetsController (D:/workspace/.....
我已经在 karma.config.js 中拥有所有需要的文件...
如果我在控制器中注释这两行。
//active: otpConfigureDatasetSelectedTab.tab == 'MyReviewList'
和
//active: otpConfigureDatasetSelectedTab.tab == 'AllDatasets'
单元测试工作正常。
我的规范定义有什么问题???
您没有保存要模拟的对象。你基本上只有
_otpConfigureDatasetService_ = undefined,
_otpReviewListDatasetsService_ = undefined
所以失败的不是控制器,而是单元测试。您正在注入 undefined
来代替这两个对象。我不确定你到底想做什么,但你要么需要定义一些模拟对象,比如 _otpConfigureDatasetService_ = {tab: 'something'}
,要么获取真正的服务并调整它们
beforeEach(inject(function ($controller, $rootScope, otpConfigureDatasetService, otpReviewListDatasetsService) {
//
_otpConfigureDatasetService_ = otpConfigureDatasetService;
_otpReviewListDatasetsService_ = otpReviewListDatasetsService;
//
scope = $rootScope.$new();
MainCtrl = $controller('otpConfigureDatasetsController', {
$scope: scope, otpWebMapApp: _otpWebMapApp_, otpWMDeltaTracker: _otpWMDeltaTracker_, otpWMStateCache: _otpWMStateCache_,
otpConfigureDatasetService: _otpConfigureDatasetService_, otpAllDatasetsService: _otpAllDatasetsService_,
otpReviewListDatasetsService: _otpReviewListDatasetsService_, otpConfigureDatasetSelectedTab: _otpConfigureDatasetSelectedTab_
});
}));
顺便说一句,惯例是在注入函数中定义_object_
,然后保存它。如果你注入它们的调用方式,那么你不需要为你的局部变量使用 _object_
形式。
我也更喜欢使用 $injector
beforeEach( inject(function($injector) {
exampleService = $injector.get('exampleService');
}));
我需要通过大量注入(服务、工厂、值)来测试控制器,现在我遇到了一个值问题...
我有以下情况:
这是我的控制器。
(function () {
'use strict';
angular
.module('otpConfigureDatasets')
.controller('otpConfigureDatasetsController', otpConfigureDatasetsController);
otpConfigureDatasetsController.$inject = ['$location', '$state', 'otpWebMapApp', 'otpWMDeltaTracker', 'otpWMStateCache', '$scope', '$timeout', 'otpConfigureDatasetService', 'otpAllDatasetsService', 'otpReviewListDatasetsService','otpConfigureDatasetSelectedTab'];
function otpConfigureDatasetsController($location, $state, otpWebMapApp, otpWMDeltaTracker, otpWMStateCache, $scope, $timeout, otpConfigureDatasetService, otpAllDatasetsService, otpReviewListDatasetsService, otpConfigureDatasetSelectedTab) {
var vm = this;
...
vm.tabs = [{
title: 'MY REVIEW LIST',
selectedAmt: vm.reviewData,
contentTemplate: './app/features/configureDatasets/reviewListDatasets.html',
active: otpConfigureDatasetSelectedTab.tab == 'MyReviewList'
}, {
title: 'ALL DATASETS',
selectedAmt: vm.allData,
contentTemplate: './app/features/configureDatasets/allDatasets.html',
active: otpConfigureDatasetSelectedTab.tab == 'AllDatasets'
}];
...
}
})();
下面是我的Spec.js
'use strict';
describe('Test', function () {
var MainCtrl, scope, _otpWebMapApp_, _otpWMDeltaTracker_, _otpWMStateCache_, _otpConfigureDatasetService_,
_otpAllDatasetsService_, _otpReviewListDatasetsService_, _otpConfigureDatasetSelectedTab_;
beforeEach(function () {
module('otpConfigureDatasets');
});
beforeEach(inject(function ($controller, $rootScope) {
scope = $rootScope.$new();
MainCtrl = $controller('otpConfigureDatasetsController', {
$scope: scope, otpWebMapApp: _otpWebMapApp_, otpWMDeltaTracker: _otpWMDeltaTracker_, otpWMStateCache: _otpWMStateCache_,
otpConfigureDatasetService: _otpConfigureDatasetService_, otpAllDatasetsService: _otpAllDatasetsService_,
otpReviewListDatasetsService: _otpReviewListDatasetsService_, otpConfigureDatasetSelectedTab: _otpConfigureDatasetSelectedTab_
});
}));
it('Should be true', function () {
expect(true).toBe(true);
});
});
但是当我尝试 运行 测试用例时,它不起作用并显示以下错误:
INFO [karma]: Karma v0.12.37 server started at http://localhost:9876/
INFO [launcher]: Starting browser PhantomJS
INFO [PhantomJS 1.9.8 (Windows 8 0.0.0)]: Connected on socket NHknSeC3p_h_lf12SK Gh with id 27552356
PhantomJS 1.9.8 (Windows 8 0.0.0) Test Should be true FAILED
TypeError: 'undefined' is not an object (evaluating 'otpConfigureDatasetSelectedTab.tab')
at otpConfigureDatasetsController (D:/workspace/.....
我已经在 karma.config.js 中拥有所有需要的文件...
如果我在控制器中注释这两行。
//active: otpConfigureDatasetSelectedTab.tab == 'MyReviewList'
和
//active: otpConfigureDatasetSelectedTab.tab == 'AllDatasets'
单元测试工作正常。
我的规范定义有什么问题???
您没有保存要模拟的对象。你基本上只有
_otpConfigureDatasetService_ = undefined,
_otpReviewListDatasetsService_ = undefined
所以失败的不是控制器,而是单元测试。您正在注入 undefined
来代替这两个对象。我不确定你到底想做什么,但你要么需要定义一些模拟对象,比如 _otpConfigureDatasetService_ = {tab: 'something'}
,要么获取真正的服务并调整它们
beforeEach(inject(function ($controller, $rootScope, otpConfigureDatasetService, otpReviewListDatasetsService) {
//
_otpConfigureDatasetService_ = otpConfigureDatasetService;
_otpReviewListDatasetsService_ = otpReviewListDatasetsService;
//
scope = $rootScope.$new();
MainCtrl = $controller('otpConfigureDatasetsController', {
$scope: scope, otpWebMapApp: _otpWebMapApp_, otpWMDeltaTracker: _otpWMDeltaTracker_, otpWMStateCache: _otpWMStateCache_,
otpConfigureDatasetService: _otpConfigureDatasetService_, otpAllDatasetsService: _otpAllDatasetsService_,
otpReviewListDatasetsService: _otpReviewListDatasetsService_, otpConfigureDatasetSelectedTab: _otpConfigureDatasetSelectedTab_
});
}));
顺便说一句,惯例是在注入函数中定义_object_
,然后保存它。如果你注入它们的调用方式,那么你不需要为你的局部变量使用 _object_
形式。
我也更喜欢使用 $injector
beforeEach( inject(function($injector) {
exampleService = $injector.get('exampleService');
}));