【发布时间】:2016-08-11 16:44:58
【问题描述】:
我正在尝试在控制器中对我的状态进行单元测试。我想要做的是将我的items 工厂存根,因为我有单独的单元测试来涵盖该功能。我很难让$injector 实际注入工厂,但似乎我让$provider 知道我想在实例化控制器时使用我的假项目对象。作为免责声明,我是 Angular 的新手,如果我的代码看起来很糟糕,我会喜欢一些建议。
目前,当我运行测试时,我收到消息:
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 测试中使用真实路由器对应用进行测试。 -
我喜欢这个建议。我尝试以与
items相同的方式删除$stateProvider和$urlRouterProvider,但不幸的是,我仍然看到与上述相同的错误 -
我已经发布了一个解释这一点的答案。请注意,在这种情况下,您不需要使用
$state.go对其进行测试(并且在本规范中根本没有$state服务)。
标签: angularjs unit-testing angular-ui-router