Reputation:
I was trying out jasmine with karma. I have a custom service ApiService which i need to inject in my spec file. But when am trying to inject the ApiService i get Error: [$injector:unpr] Unknown provider: ApiService <- ApiService
this is my controller
'use strict';
angular.module('assessmentApp')
.controller('NewUserController', NewUserController)
.run(["$rootScope", "$anchorScroll", function($rootScope, $anchorScroll) {
$rootScope.$on("$locationChangeSuccess", function() {
$anchorScroll();
});
}]);
NewUserController.$inject = ['$scope', '$rootScope', '$location', '$timeout', 'ApiService'];
function NewUserController($scope, $rootScope, $location, $timeout, ApiService) {
//console.log("innn NewUserController2 ::::")
var vm = this;
var boardsClassSubjectCombinations = [];
var studentId = $rootScope.globals.studentId;
var assessmentCampaignId = $scope.assessmentCampaignId = $rootScope.globals.assessmentCampaignId;
vm.currentQuestion = 1;
//sanity check if the user already has academics added
ApiService.getAll('students/' + studentId + '/latest-student-academic', true, ['students/{{id}}/academic'])
.then(function(res) {
if (res.data) {
//send this guy to home page
$location.url('/home');
}
});
function getStates() {
ApiService.getAll('states', true).then(function(response) {
$scope.states = response.data;
});
}
getStates();
}
this is my test file
describe('NewUserController Test', function() {
beforeEach(module('assessmentApp'));
// beforeEach(module('assets'));
//beforeEach(module('ApiService'))
var scope, location, timeout,apiService, q, authenticationService;
beforeEach(inject(function($location,$rootScope,$timeout, ApiService){
scope = $rootScope.$new();
location = $location;
timeout = $timeout;
q = _$q_;
console.log(ApiService)
//spyOn(ApiService, 'ApiService');
//spyOn(Point, 'method');
// console.log("ApiService :::"+ApiService)
//$controller = _$controller_('NewUserController', { $scope: $scope });
//console.log("NewUserController======="+$controller)
}));
describe('$scope.grade', function() {
it('sets the strength to "strong" if the password length is >8 chars', function() {
console.log("$location ::::"+location)
console.log("scope ::::"+scope)
console.log("timeout ::::"+timeout)
console.log("ApiService ::::"+ApiSrvce)
console.log("q ::::"+q)
//console.lopg("authenticationService :::"+authenticationService)
//console.log("$scope ::::::"+$scope)
expect(true).toEqual(true);
});
});
});
This is my karma.conf.js file
module.exports = function(config) {
config.set({
// base path that will be used to resolve all patterns (eg. files, exclude)
basePath: '',
// frameworks to use
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: ['jasmine'],
// list of files / patterns to load in the browser
files: [
//'test-main.js',
'../bower_components/jquery/dist/jquery.js',
'../bower_components/angular/angular.js',
'../bower_components/bootstrap/dist/js/bootstrap.js',
'../bower_components/angular-route/angular-route.js',
'../bower_components/particles.js/particles.js',
'../bower_components/angular-cookies/angular-cookies.js',
'../bower_components/toastr/toastr.js',
'../bower_components/angular-sanitize/angular-sanitize.js',
'../bower_components/d3/d3.js',
'../bower_components/c3/c3.js',
'../bower_components/moment/moment.js',
'../bower_components/humanize-duration/humanize-duration.js',
'../bower_components/angular-timer/dist/angular-timer.js',
'../bower_components/underscore/underscore.js',
'../bower_components/scrollreveal/dist/scrollreveal.js',
'../bower_components/lodash/lodash.js',
'../bower_components/angular-youtube-mb/src/angular-youtube-embed.js',
'../bower_components/angular-mocks/angular-mocks.js',
//'../assets/**/*.js',
//'../assets/**/*.html',
//'../bower_components/angular/angular.js',
//'../bower_components/angular-mocks/angular-mocks.js',
'../app/scripts/app.js',
'../app/scripts/controllers/**/*.js',
'../app/scripts/directives/**/*.js',
'../app/scripts/services/**/*.js',
'../app/scripts/**/*.js',
'../../assets/src/assets/services/*.js',
'spec/**/*.js'
],
// list of files to exclude
exclude: [
],
// preprocess matching files before serving them to the browser
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {
},
// test results reporter to use
// possible values: 'dots', 'progress'
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
reporters: ['progress'],
// web server port
port: 9876,
// enable / disable colors in the output (reporters and logs)
colors: true,
// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO,
// enable / disable watching file and executing tests whenever any file changes
autoWatch: true,
// start these browsers
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
browsers: ['PhantomJS'],
// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
singleRun: false,
// Concurrency level
// how many browser should be started simultaneous
concurrency: Infinity
})
}
What i see is, when i try to inject any custom service it skips the beforeEach function and the logs i get in it function is
LOG: '$location ::::undefined'
LOG: 'scope ::::undefined'
LOG: 'timeout ::::undefined'
LOG: 'ApiService ::::undefined'
Upvotes: 0
Views: 1450
Reputation: 5957
So I would suggest this kind of structure:
angular.mock.module(function($provide) {
apiService = jasmine.createSpy('apiService', ['getAll']);
$provide.value('apiService', apiService);
// Mock out other services here in the same fashion;
});
inject(function(_$controller_, _$rootScope_) {
$controller =
_$controller_('NewUserController', { $scope: _$rootScope_.$new() });
});
Then in your tests, you would refer to the apiService like this. Ideally you would make an it() statement for each bit you want to test, like say, the return value of getState(), but we'll do it all in one here:
it ('calls getState()', function () {
// Mock out what the apiService will do; you only care what comes back
// so you can see what $scope.states looks like in the end;
apiService.getAll.and.returnValue({ Promise.resolve({ foo: 1 }) });
// Spy on the controller's own getState method;
spyOn($controller, 'getState').and.callFake(() => true);
// Store the return value of the getState call;
expect($controller.getState).toHaveBeenCalled();
// Overall the calls count for getAll on the apiService should be two;
expect(apiService.getAll.calls.count()).toEqual(2);
// getState() will have been called, and should return the object;
expect($controller.states).toEqual({ foo: 1 });
});
Upvotes: 1