I'm trying to work out how to unit test my login controller with Karma/Jasmine/Mocha.
I basically want to test if a 200 comes back from the $auth.login()
then the message saved should be equal to "successfully logged in",
otherwise if I receive a 401 then the message that comes back should be "error logging in".
UPDATE
This is where I'm at, at the moment.
login.controller.js
function loginCtrl($auth, $scope, $rootScope, $location) {
var vm = this;
vm.login = function() {
var credentials = { email: vm.email, password: vm.password };
// Use Satellizer's $auth service to login
$auth.login(credentials).then(function() {
vm.message = "Successfully logged in!";
}, function(error) {
vm.message = "Error logging in!";
}).then(function(responses) {
$location.path('home');
});
};
}
login.controller.spec.js
describe('Login Controller', function() {
var q, scope, ctrl, auth;
beforeEach(module('app.login'));
beforeEach(inject(function($q, $rootScope, $controller, $auth) {
q = $q;
scope = $rootScope.$new();
ctrl = $controller('loginCtrl', { $scope: scope, SessionService: sessionService, $auth: auth, $q: q });
auth = $auth;
}));
it('should present a successfull message when logged in', function () {
var defer = q.defer();
sinon.stub(auth, 'login')
.withArgs({ email: 'test@test.com', password: 'test_password' })
.returns(defer.promise);
ctrl.login();
defer.resolve();
scope.$apply();
expect(ctrl.message).to.equal('Successfully logged in!');
});
});
Since this is your controller test, you'd probably need to spyOn
your service ($auth
) like so (in Jasmine) -
var defer = $q.defer();
spyOn('$auth', login).andReturn(defer.promise);
controller.email = 'test@test.com';
controller.password = 'test_password';
controller.login();
defer.resolve();
scope.$apply();
expect($auth.login).toHaveBeenCalledWith({ email: 'test@test.com', password: 'test_password' });
expect(scope.message).toEqual("successfully logged in");
and for the failure case using defer.reject()
and pretty much the same format for assertion.
In my opinion, you'd end up worrying about http
related status-codes or responses only at the service
level and not at the controller
level. There you'd use $httpBackend
to mock the responses with their status-codes and the corresponding responses.
EDIT
In mocha, as per my research, you'd end up doing something like -
sinon.stub($auth, 'login')
.withArgs({ email: 'test@test.com', password: 'test_password' })
.returns(defer.promise);
to stub
the method. And the verification of the call as -
sinon.assert.calledOnce($auth.login);
Rest of it remains the same. The assertion of the message will also change to assert.equal
for mocha.
EDIT
Checkout this fiddle - http://jsfiddle.net/9bLqh5zc/. It uses 'sinon' for the spy and 'chai' for assertion