Reputation: 446
Does anyone know how to unit test resolve block items in a routed component? It would be great if anyone can test courseDetails in the resolve block as an example.
(function() {
'use strict';
angular
.module('writingsolutionsComponents')
.component('courseSettings', {
bindings: {
newCourseForm: '<',
courseDetails: '<',
timezones: '<',
citations: '<',
disciplines: '<'
},
templateUrl: 'course-settings/course-settings.html',
controller: 'CourseSettingsController'
})
.config(stateConfig);
stateConfig.$inject = ['$stateProvider'];
function stateConfig($stateProvider, $urlRouterProvider) {
$stateProvider.state('course-settings', {
parent: 'app',
url: '/:courseId/course-settings',
data: {
pageTitle: "Hello World"
},
views: {
'content@': {
component: 'courseSettings'
}
},
resolve: {
courseDetails: function(CourseService, $stateParams) {
return CourseService.get($stateParams.courseId);
},
timezones: function(TimezoneService) {
return TimezoneService.getTimeZones();
},
citations: function(CitationService) {
return CitationService.getCitations();
},
disciplines: function(DisciplineService) {
return DisciplineService.getAllDisciplines();
}
}
}
});
}
})();
I tried following and it didn't workout for me.
CourseServiceMock = {
get: function () {
return $q.resolve({courseId: "32432535", title: "Communication"});
}
};
spyOn(CourseServiceMock , 'get').and.callThrough();
expect(CourseServiceMock .get).toHaveBeenCalled()
Upvotes: 2
Views: 863
Reputation: 31823
Do not test your framework(s). Here that means do not test ui-router, it is known to work correctly. Specifically, we know it is going to call the registered resolve functions.
If you wish to test the resolve function itself, it is actually quite simple. We just need to make the function available to test. We can actually test this function without launching a web browser or doing anything fancy.
Here is an example that uses a test library called blue-tape* to run the test using NodeJS, you can adapt it to use Jasmine if you must.
// tests.js
const test = require("blue-tape");
test("courseDetails resolve retrieves the course based on route/:courseId", async t => {
// arrange
const courses = [{courseId: "32432535", title: "Communication"}];
const mockCourseService = {
get(id) {
return Promise.resolve(courses.find(course => course.id === id));
}
};
const mock$stateParams = {courseId: "32432535"};
// act
const result = await courseDetails(mockCourseService, mock$stateParams);
// assert
t.equal(result.courseId, courses[0].courseId);
});
To get this working, run
npm install --save-dev blue-tape
And then run
node test.js
The benefit is that your test does not depend on ui-router or even AngularJS and that it just tests what you care about, your business logic.
Note, this test itself is a bit arbitrary.
*I am using blue-tape instead of tape here because it makes testing asynchronous functions very simple as it automatically handles any function that returns a thennable.
Upvotes: 1