1

I think I do everything the same way as in tutorials and there is weird bug. I want to mock $http in my LoginService and test it. Unfortunately there are some problems - it looks like it doesn't see $httpBackend functions. This is my LoginService:

app.factory('LoginService', function($http) {
//..
    var validateUser = function(username, password){
        $http.post('http://domain/api/login',
        {
            username: username,
            password: password
        })
        .success(function (data) {
            //...
        });
    };

    return {
        validateUser: validateUser,
        getLoginState: getLoginState
    };
});

And there is test for that validateUser function:

describe('LoginService', function() {
var httpBackend, LoginService;
beforeEach(module('app'));

beforeEach(inject(function ($httpBackend, _LoginService_) {
    LoginService = _LoginService_;
    httpBackend = $httpBackend;
}));

afterEach(function() {
    httpBackend.verifyNoOutstandingExpectation();
    httpBackend.verifyNoOutstandingRequest();
});

it('changes loginState object when user exists', inject(function(){
    data = {username: "ut_user", token: "123456"}; 
    httpBackend.expectPOST('http://domain/api/login').respond(data);
    LoginService.validateUser("user", "pass");
    httpBackend.flush();
    expect(LoginService.getLoginState().loggedIn).toBe(true);
}));
});

And there is error which was on httpBackend.verifyNoOutstandingExpectation(); and previously on httpBackend.flush():

ReferenceError: $ is not defined
at http://localhost:9876/base/js/routes.js:21:34
at Scope.$broadcast (http://localhost:9876/base/node_modules/angular/angular.js:16200:28)
at http://localhost:9876/base/node_modules/angular/angular.js:12231:45
at Scope.$eval (http://localhost:9876/base/node_modules/angular/angular.js:15878:28)
at Scope.$digest (http://localhost:9876/base/node_modules/angular/angular.js:15689:31)
at Function.$httpBackend.verifyNoOutstandingExpectation (http://localhost:9876/base/node_modules/angular-mocks/angular-mocks.js:1563:38)
at Object.<anonymous> (http://localhost:9876/base/spec/services/loginServiceSpec.js:11:21)
at attemptSync (http://localhost:9876/base/node_modules/jasmine-core/lib/jasmine-core/jasmine.js:1789:24)
at QueueRunner.run (http://localhost:9876/base/node_modules/jasmine-core/lib/jasmine-core/jasmine.js:1777:9)
at QueueRunner.execute (http://localhost:9876/base/node_modules/jasmine-core/lib/jasmine-core/jasmine.js:1762:10)

I have in karma conf:

files: [
    'node_modules/angular/angular.js',
    'node_modules/angular-*/angular-*.js',
    'js/**/*.js',
    'spec/**/*.js'
],
Mossar
  • 425
  • 1
  • 5
  • 14
  • Show the complete stack trace. – JB Nizet Sep 18 '15 at 13:48
  • 1
    So, your routes.js file is using a variable named `$`, at line 21, that is undefined. If you use jQuery, then add it to the list of files in the karma config. – JB Nizet Sep 18 '15 at 14:59
  • Oh man, I thought it is connected with $ in $httpBackend :D Thank you very much. I will look at stacktrace more precisely next time – Mossar Sep 18 '15 at 18:50

1 Answers1

3

Your inject is incorrect

beforeEach(inject(function ($httpBackend, _LoginService_) {
    LoginService = _LoginService_;
    httpBackend = $httpBackend;
}));

should instead be

beforeEach(inject(function (_$httpBackend_, _LoginService_) {
    LoginService = _LoginService_;
    httpBackend = _$httpBackend_;
}));
Jonnus
  • 2,988
  • 2
  • 24
  • 33