我試圖在控制器中對我的狀態進行單元測試。我想要做的是剔除我的items
工廠,因爲我有單獨的單元測試涵蓋了該功能。我很難讓$injector
實際注入工廠,但似乎我讓$provider
知道我想在實例化控制器時使用我的僞項目對象。作爲一個免責聲明,我是全新的角色,如果我的代碼看起來不好,我會喜歡一些建議。解決方案中使用的存根工廠
目前,當我運行測試我得到的消息:
Error: Unexpected request: GET /home.html
No more request expected
at $httpBackend (node_modules/angular-mocks/angular-mocks.js:1418:9)
at n (node_modules/angular/angular.min.js:99:53)
at node_modules/angular/angular.min.js:96:262
at node_modules/angular/angular.min.js:131:20
at m.$eval (node_modules/angular/angular.min.js:145:347)
at m.$digest (node_modules/angular/angular.min.js:142:420)
at Object.<anonymous> (spec/states/homeSpec.js:29:16)
看來,我的嘲笑項目工廠沒有被注入測試。當我將console.log
行放入要在工廠工廠中存根的方法中時,我看到該行將被調用。
我在尋找要測試的代碼如下:
angular.module('todo', ['ui.router'])
// this is the factory i want to stub out...
.factory('items', ['$http', function($http){
var itemsFactory = {};
itemsFactory.getAll = function() {
// ...specifically this method
};
return itemsFactory;
}])
.controller('TodoCtrl', ['$scope', 'items', function($scope, items) {
// Do things
}])
.config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider){
$stateProvider
.state('home', {
url: '/home',
templateUrl: '/home.html',
controller: 'TodoCtrl',
resolve: {
items: ['items', function(items){
// this is the invocation that i want to use my stubbed method
return items.getAll();
}]
}
});
$urlRouterProvider.otherwise('home');
}]);
我的測試是這樣的:
describe('home state', function() {
var $rootScope, $state, $injector, state = 'home';
var getAllStub = sinon.stub();
var items = {
getAll: getAllStub
};
beforeEach(function() {
module('todo', function($provide) {
$provide.value('items', items);
});
inject(function(_$rootScope_, _$state_, _$injector_) {
$rootScope = _$rootScope_;
$state = _$state_;
$injector = _$injector_;
});
});
it('should resolve items', function() {
getAllStub.returns('getAll');
$state.go(state);
$rootScope.$digest();
expect($state.current.name).toBe(state);
expect($injector.invoke($state.current.resolve.items)).toBe('findAll');
});
});
預先感謝您的幫助!
你嘲笑的工廠很好。由於請求了「/home.html」模板,因此出現錯誤。在單元測試中允許真正的路由器是一個壞主意,因爲它打破了隔離並增加了更多移動部分。我個人認爲'$ stateProvider'等存根更好的測試策略。您只需確保使用期望的配置對象作爲參數調用'$ stateProvider.state'。如有必要,應用程序可以在集成/ e2e測試中使用真正的路由器進行測試。 – estus
我喜歡這個建議。我嘗試用'items'方式去掉'$ stateProvider'和$ $ urlRouterProvider',但不幸的是我仍然看到與上面相同的錯誤 – davidicus
我發佈了一個解釋這個問題的答案。注意,在這種情況下你不需要用'$ state.go'來測試它(並且在這個規範中根本沒有'$ state'服務)。 – estus