我已經發現,以測試這種類型的場景被移動到待測試移至單獨的依賴性的方法,則在控制器中注入它,並提供在試驗中假代替的唯一方法。
這是一個非常基本的工作例如:
angular.module('test', [])
.factory('loadResponses', function() {
return function() {
//do something
}
})
.controller('aCtrl', ['$scope', 'loadResponses', function($scope, loadResponses) {
$scope.loadResponses = loadResponses;
$scope.loadResponses();
}]);
describe('test spec', function(){
var scope;
var loadResponsesInvoked = false;
var fakeLoadResponses = function() {
loadResponsesInvoked = true;
}
beforeEach(function() {
module('test', function($provide) {
$provide.value('loadResponses', fakeLoadResponses)
});
inject(function($controller, $rootScope) {
scope = $rootScope.$new();
$controller('aCtrl', { $scope: scope });
});
});
it('should ensure that scope.loadResponses was called upon instantiation of the controller', function() {
expect(loadResponsesInvoked).toBeTruthy();
});
});
對於您可能需要額外的工作(例如,你可能不總是希望僞造loadResponses
法)現實世界中的代碼,但你的想法。
而且,這裏是一個很好的文章,介紹如何創建一個實際使用茉莉花間諜假依賴關係:Mocking Dependencies in AngularJS Tests
編輯:這裏是另一種方式,即使用$provide.delegate
並不會取代原來的方法:
describe('test spec', function(){
var scope, loadResponses;
var loadResponsesInvoked = false;
beforeEach(function() {
var loadResponsesDecorator = function ($delegate) {
loadResponsesInvoked = true;
return $delegate;
}
module('test', function($provide) {
$provide.decorator('loadResponses', loadResponsesDecorator);
});
inject(function($controller, $rootScope) {
scope = $rootScope.$new();
$controller('aCtrl', { $scope: scope });
});
});
it('should ensure that scope.loadResponses was called upon instantiation of the controller', function() {
expect(loadResponsesInvoked).toBeTruthy();
});
});
它通常會工作,但不會在這種情況下。因爲你在控制器被實例化並調用了方法之後設置了間諜。即使你在作用域上創建了一個間諜方法,它也會在控制器被實例化時被覆蓋,並且它不會真正起作用。 – PSL 2014-09-24 20:16:28
當我想到它時,你不需要測試初始化時是否調用了'$ scope.loadResponses'。因爲如果你的控制器實例化成功(沒有它,反正你的測試都不會通過),所以保證'$ scope.loadResponses'已被調用。所以我沒有看到在初始化函數上進行間諜活動。 – PSL 2014-09-24 20:49:28
在路上,我不希望開發人員將其刪除(有意或無意),因爲它獲得了使用該頁面的關鍵資源。我能夠檢查一個變量是否在初始化後被分配了預期的值,我有點驚訝,我無法使用間諜來檢查初始化調用。 – 2014-09-24 21:09:23