I have below controller to get the books list and single books detail. It's working as expected but the unit test is not working as expected.
books.controller.js
var myApp = angular.module('myApp');
function BooksController($log, $routeParams, BooksService) {
// we declare as usual, just using the `this` Object instead of `$scope`
const vm = this;
const routeParamId = $routeParams.id;
if (routeParamId) {
BooksService.getBook(routeParamId)
.then(function (data) {
$log.info('==> successfully fetched data for book id:', routeParamId);
vm.book = data;
})
.catch(function (err) {
vm.errorMessage = 'OOPS! Book detail not found';
$log.error('GET BOOK: SOMETHING GOES WRONG', err)
});
}
BooksService.getBooks()
.then(function (data) {
$log.info('==> successfully fetched data');
vm.books = data;
})
.catch(function (err) {
vm.errorMessage = 'OOPS! No books found!';
$log.error('GET BOOK: SOMETHING GOES WRONG', err)
});
}
BooksController.$inject = ['$log', '$routeParams', 'BooksService'];
myApp.controller('BooksController', BooksController);
Spec for above controller in which I want to test the getBook(id) service but somehow I am not able to pass the id of book.
describe('Get All Books List: getBooks() =>', () => {
const errMsg = 'OOPS! No books found!';
beforeEach(() => {
// injecting rootscope and controller
inject(function (_$rootScope_, _$controller_, _$q_, BooksService) {
$scope = _$rootScope_.$new();
$service = BooksService;
$q = _$q_;
deferred = _$q_.defer();
// Use a Jasmine Spy to return the deferred promise
spyOn($service, 'getBooks').and.returnValue(deferred.promise);
// The injector unwraps the underscores (_) from around the parameter names when matching
$vm = _$controller_('BooksController', {$scope: $scope, $service: BooksService});
});
});
it('should defined getBooks $http methods in booksService', () => {
expect(typeof $service.getBooks).toEqual('function');
});
it('should able to fetch data from getBooks service', () => {
// Setup the data we wish to return for the .then function in the controller
deferred.resolve([{ id: 1 }, { id: 2 }]);
// We have to call apply for this to work
$scope.$apply();
// Since we called apply, now we can perform our assertions
expect($vm.books).not.toBe(undefined);
expect($vm.errorMessage).toBe(undefined);
});
it('should print error message if data not fetched', () => {
// Setup the data we wish to return for the .then function in the controller
deferred.reject(errMsg);
// We have to call apply for this to work
$scope.$apply();
// Since we called apply, now we can perform our assertions
expect($vm.errorMessage).toBe(errMsg);
});
});
describe('Get Single Book Detail: getBook() =>', () => {
const errMsg = 'OOPS! Book detail not found';
const routeParamId = '59663140b6e5fe676330836c';
beforeEach(() => {
// injecting rootscope and controller
inject(function (_$rootScope_, _$controller_, _$q_, BooksService) {
$scope = _$rootScope_.$new();
$scope.id = routeParamId;
$service = BooksService;
$q = _$q_;
var deferredSuccess = $q.defer();
// Use a Jasmine Spy to return the deferred promise
spyOn($service, 'getBook').and.returnValue(deferredSuccess.promise);
// The injector unwraps the underscores (_) from around the parameter names when matching
$vm = _$controller_('BooksController', {$scope: $scope, $service: BooksService});
});
});
it('should defined getBook $http methods in booksService', () => {
expect(typeof $service.getBook).toEqual('function');
});
it('should print error message', () => {
// Setup the data we wish to return for the .then function in the controller
deferred.reject(errMsg);
// We have to call apply for this to work
$scope.$apply();
// expect($service.getBook(123)).toHaveBeenCalled();
// expect($service.getBook(123)).toHaveBeenCalledWith(routeParamId);
// Since we called apply, now we can perform our assertions
expect($vm.errorMessage).toBe(errMsg);
});
});
"Get Single Book Detail: getBook()" this suit is not working. Please help me, how to short out this kind of situation.
Error I am getting is below
Chrome 59.0.3071 (Mac OS X 10.12.5) Books Controller Get Single Book Detail: getBook() => should print error message FAILED
Expected 'OOPS! No books found!' to be 'OOPS! Book detail not found'.
Chrome 59.0.3071 (Mac OS X 10.12.5) Books Controller Get Single Book Detail: getBook() => should print error message FAILED
Expected 'OOPS! No books found!' to be 'OOPS! Book detail not found'.
at Object.it (test/client/controllers/books.controller.spec.js:108:38)
Chrome 59.0.3071 (Mac OS X 10.12.5): Executed 7 of 7 (1 FAILED) (0 secs / 0.068 secs)
.
Chrome 59.0.3071 (Mac OS X 10.12.5): Executed 7 of 7 (1 FAILED) (0.005 secs / 0.068 secs)