I have Angular with ui-router, so toResolve
variable will be resolved in my SomeController
.state('some.state', {
url: '/some',
controller: 'SomeController',
templateUrl: '/static/views/some-state.html',
resolve: {
toResolve: function(Resource) {
return Resource.get(function(response) {
return response;
});
},
But how to test this functionality with Jasmine? Let's suppose that I forget return
statement, therefore the toResolve
in my scope will be undefined.
Use services to make resolvers efficiently testable (and also mockable in integration/e2e tests).
Note: Angular services are singletons, state/route resolvers are not.
If caching a resolution is expected, a resolver may be moved to factory
service.
app.factory('someResolver', function(Resource) {
return Resource.get(function(response) {
return response;
})
});
...
resolve: { toResolve: 'someResolver' },
On the other hand, if the resolver is expected to be evaluated on each route change, this may lead to undesirable app behaviour. In this case the appropriate recipe may be constant
annotated function:
app.constant('someResolver', ['Resource', function(Resource) {
return Resource.get(function(response) {
return response;
})
}]);
app.config(function (someResolver, ...) {
...
resolve: { toResolve: someResolver },
...
Otherwise the specs may end encumbered with a pile of boilerplate code:
var toResolveFactory = $state.get('some.state').resolve.toResolve;
var toResolve = $injector.invoke(toResolveFactory);
One good article on related topic is http://nikas.praninskas.com/angular/2014/09/27/unit-testing-ui-router-configuration/, but it's not the solution. One idea is to pass another object to resolve
and then test that unit of code separately which is good when you're resolving a bunch of items.