En essayant de comprendre le Jasmine's toHaveBeenCalled () matcher

Je suis nouveau dans jasmine ici est mon fichier src dans lequel je crée la classe Auth

 function Auth() { } Auth.prototype.isEmpty = function(str) { return (!str || 0 === str.length); } Auth.prototype.Login = function (username , password) { if (this.isEmpty(username) || this.isEmpty(password)) { return "Username or Password cann't be blank "; } else { return "Logged In !"; } } 

Maintenant je veux tester jasmine toHaveBeenCalled() matcher. Voici ce que j'écris

 it("should be able to Login", function () { spyOn(authobj); expect(authobj.Login('abc', 'abc')).toHaveBeenCalled(); }); 

Mais il dit que la undefined() method does not exist

EDIT: Regardez la réponse basecode pour une meilleure approche


Du docs , vous devriez l'utiliser comme suit:

 spyOn(foo, 'setBar'); it("tracks that the spy was called", function() { expect(foo.setBar).toHaveBeenCalled(); }); 

Donc, vous devriez écrire:

 it("should be able to Login", function () { spyOn(authobj, 'isEmpty'); authobj.Login('abc', 'abc'); expect(authobj.isEmpty).toHaveBeenCalled(); }); 

En regardant votre cas d'utilisation, je ne peux pas recommander l'utilisation de ce toHaveBeenCalled ici. toHaveBeenCalled est utile dans les cas où vous souhaitez des rappels de test (async) ou en combinaison avec des balises.

Considérez tout ce qui se passe dans Auth.prototype.Login comme détail d'implémentation qui n'est pas visible pour le "monde extérieur". Vous ne devez pas tester les détails d'implémentation. Ce qui déclenche deux questions.

Pourquoi ne pas tester les détails d'implémentation?

Il rend difficile le refactoring. Disons que vous souhaitez remplacer Auth.prototype.isEmpty pour certaines raisons par underscore.isEmpty . Quelques jours plus tard, vous décidez de remplacer complètement le underscore par lodash . Cela vous obligerait à changer votre test trois fois. Considérez tout ce qui vous empêche de refactoriser facilement en tant que "non-go".

Que dois-je tester à la place?

API publique. Tout ce qui est visible pour le "monde extérieur". Ce qui est dans votre cas "Connecté!" Et "Nom d'utilisateur ou mot de passe ne peut pas être vide".

Ce qui aboutit à 3 tests:

 describe('Login', function() { it('returns "success" string when username and password are not empty', function() { expect(new Auth().Login('non-empty', 'non-empty')).toBe('Logged In !'); }); it('returns "failure" string when username is empty', function() { expect(new Auth().Login('', 'non-empty')).toBe('Username or Password cannot be blank'); }); it('returns "failure" string when password is empty', function() { expect(new Auth().Login('non-empty', '')).toBe('Username or Password cannot be blank'); }); }); 

C'est simple à utiliser, essentiellement: –

 spyOn(<name_of_the_object>, '<name_of_the_method>') expect(<name_of_the_object>.<name_of_the_method>).toHaveBeenCalled();