Я пытаюсь выполнить тестирование моих состояний в контроллере. Что я хочу сделать, это закрыть мою фабрику 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
Мне нравится это предложение. Я попытался вытеснить '$ stateProvider' и' $ urlRouterProvider' так же, как и с 'items', но, к сожалению, я все еще вижу ту же ошибку, что и выше – davidicus
. Я опубликовал ответ, который объясняет это. Обратите внимание, что вам не нужно проверять его с помощью '$ state.go' в этом случае (и в этой спецификации не будет никакой службы' $ state'). – estus