我在应用程序中测试路由器时遇到了一些麻烦,该应用程序是基于Angular ui路由器构建的。我要测试的是状态转换是否适当地更改了URL(稍后将进行更复杂的测试,但这是我开始的地方。)
这是我的应用程序代码的相关部分:
angular.module('scrapbooks') .config( function($stateProvider){ $stateProvider.state('splash', { url: "/splash/", templateUrl: "/app/splash/splash.tpl.html", controller: "SplashCtrl" }) })
和测试代码:
it("should change to the splash state", function(){ inject(function($state, $rootScope){ $rootScope.$apply(function(){ $state.go("splash"); }); expect($state.current.name).to.equal("splash"); }) })
关于Stackoverflow的类似问题(以及官方ui路由器测试代码)表明,将$ state.go调用包装在$ apply中应该足够了。但是我已经做到了,状态仍然没有更新。$ state.current.name保持为空。
同样也遇到了这个问题,最终找到了解决方法。
这是一个示例状态:
angular.module('myApp', ['ui.router']) .config(['$stateProvider', function($stateProvider) { $stateProvider.state('myState', { url: '/state/:id', templateUrl: 'template.html', controller: 'MyCtrl', resolve: { data: ['myService', function(service) { return service.findAll(); }] } }); }]);
下面的单元测试将涵盖测试带参数的URL,以及执行注入自身依赖关系的解析:
describe('myApp/myState', function() { var $rootScope, $state, $injector, myServiceMock, state = 'myState'; beforeEach(function() { module('myApp', function($provide) { $provide.value('myService', myServiceMock = {}); }); inject(function(_$rootScope_, _$state_, _$injector_, $templateCache) { $rootScope = _$rootScope_; $state = _$state_; $injector = _$injector_; // We need add the template entry into the templateCache if we ever // specify a templateUrl $templateCache.put('template.html', ''); }) }); it('should respond to URL', function() { expect($state.href(state, { id: 1 })).toEqual('#/state/1'); }); it('should resolve data', function() { myServiceMock.findAll = jasmine.createSpy('findAll').and.returnValue('findAll'); // earlier than jasmine 2.0, replace "and.returnValue" with "andReturn" $state.go(state); $rootScope.$digest(); expect($state.current.name).toBe(state); // Call invoke to inject dependencies and run function expect($injector.invoke($state.current.resolve.data)).toBe('findAll'); }); });