How can I unit test different views for the below scenario
.state('app.sr.product.upload', {
name: 'upload',
url: '/upload',
data: {
tags: [],
userCommunities: []
},
views: {
"[email protected]": {
templateUrl: 'views/upload/upload.html',
controller: 'UploadCtrl',
controllerAs: 'ul'
},
"[email protected]": {
templateUrl: 'views/tags/tags.html',
controller: 'TagsCtrl',
controllerAs: 'vm'
},
"[email protected]": {
templateUrl: 'views/user-community/user-community.html',
controller: 'UserCommunityCtrl',
controllerAs: 'ul'
},
}
})
If my view is [email protected]
then how can I test that
my controller is TagsCtrl, my controllerAs value is vm etc??
How can I unit test if my state is app.sr.product.upload
then
data.tags=[], data.userCommunities=[]
etc.
I searched for lot of docs and tutorials but didnt get it .
Any help is appreciable. Thanks
Try this on for size. I'm assuming you would be using jasmine for your tests, but the concept is the same for any testing framework.
When you run your test, first subscribe to the '$stateChangeSuccess'
event and then navigate to that state. Once the event fires, check the toState values to see if they are what you expect them to be.
You can run the snippet to see the tests in action.
//write a unit test
describe('state changes', function() {
beforeEach(module('app'));
var $rootScope, $state;
beforeEach(inject(function(_$rootScope_, _$state_) {
// The injector unwraps the underscores (_) from around the parameter names when matching
$rootScope = _$rootScope_;
$state = _$state_;
}));
it('loads page 1', function(done) {
//wait for the state to change, then make sure we changed to the correct state
$rootScope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState, fromParams) {
expect(toState.controller).toEqual('Controller1');
done();
});
//navigate to the state
$state.go('state1');
//start a digest cycle so ui-router will navigate
$rootScope.$apply();
});
it('loads page 2', function(done) {
//wait for the state to change, then make sure we changed to the correct state
$rootScope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState, fromParams) {
expect(toState.controller).toEqual('Controller2');
done();
});
//navigate to the state
$state.go('state2');
//start a digest cycle so ui-router will navigate
$rootScope.$apply();
});
it('loads page 3', function(done) {
//wait for the state to change, then make sure we changed to the correct state
$rootScope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState, fromParams) {
expect(toState.controller).toEqual('Controller3');
done();
});
//navigate to the state
$state.go('state3');
//start a digest cycle so ui-router will navigate
$rootScope.$apply();
});
});
//set up some dummy controllers and some dummy states
angular.module('app', ['ui.router']).controller('Controller1', function() {
this.message = 'Page 1';
}).controller('Controller2', function() {
this.message = 'Page 2';
}).controller('Controller3', function() {
this.message = 'Page 3';
}).config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise("/state1");
$stateProvider.state('state1', {
url: "/state1",
controller: 'Controller1',
controllerAs: 'vm',
template: '<h1>{{vm.message}}</h1>'
}).state('state2', {
url: "/state2",
controller: 'Controller2',
controllerAs: 'vm',
template: '<h2>{{vm.message}}</h2>'
}).state('state3', {
url: "/state3",
controller: 'Controller3',
controllerAs: 'vm',
template: '<h3>{{vm.message}}</h3>'
});
});
h1 {
color: red;
}
h2 {
color: blue;
}
h3 {
color: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.min.js"></script>
<script src="
https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.18/angular-ui-router.js"></script>
<link rel="stylesheet" type="text/css" href="http://jasmine.github.io/2.0/lib/jasmine.css">
<script src="http://jasmine.github.io/2.0/lib/jasmine.js"></script>
<script src="http://jasmine.github.io/2.0/lib/jasmine-html.js"></script>
<script src="http://jasmine.github.io/2.0/lib/boot.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular-mocks.js"></script>
<div ng-app="app">
<a ui-sref="state1">State 1</a>
<a ui-sref="state2">State 2</a>
<a ui-sref="state3">State 3</a>
<div ui-view></div>
</div>
If I'm not wrong, I think we missed the point of the initial question, which was
if my view is [email protected] then how can I test that my controller is TagsCtrl, my controllerAs value is vm etc??
and
How can I unit test if my state is app.sr.product.upload then data.tags=[], data.userCommunities=[] etc.
Here's how you can test these :
var $rootScope, $state, $injector, state;
beforeEach(inject(function(_$rootScope_, _$state_){
$rootScope = _$rootScope_;
$state = _$state_;
state = $state.get('app.sr.product.upload');
}));
it('should have the correct data parameters', function () {
expect(state.data.tags).toEqual('');
expect(state.data.userCommunities).toEqual('');
});
it('should render the dashboard views with the right Controllers', function () {
var product = state.views['[email protected]'];
var tags= state.views['[email protected]'];
var userCommunity = state.views['[email protected]'];
expect(product.templateUrl).toEqual('views/upload/upload.html');
expect(product.controller).toEqual('UploadCtrl');
expect(product.controllerAs).toEqual('ul');
// etc...
});
Also, in newer angular versions, you can just declare your controller like so:
controller: 'UploadCtrl as vm'
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With