Trying to understand Jasmine's toHaveBeenCalled() matcher

人盡茶涼 提交于 2019-12-06 18:38:23

问题


I am new to jasmine here is my src file in which i create Auth class

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 !";
    }
}

now i want to test jasmine's toHaveBeenCalled() matcher . Here is what i write

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

but it says that undefined() method does not exist


回答1:


EDIT: Look at basecode answer for a better approach


From the docs, you should use it like the following:

spyOn(foo, 'setBar');

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

So you should write:

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



回答2:


Looking at your use-case, I can't recommend using toHaveBeenCalled here. toHaveBeenCalled is useful in cases where you want test callbacks (async) or in combination with mocks.

Consider everything that happens within Auth.prototype.Login as implementation detail which is not visible to the "outerworld". You shouldn't test implementation details. Which triggers two questions.

Why shouldn't I test implementation details?

It makes refactoring hard. Let's say you want to replace Auth.prototype.isEmpty for some reasons by underscore.isEmpty. Some days later you decide to replace underscore completely by lodash. This would force you to change your test three times. Consider everything that prevents you from refactoring easily as a "no-go".

What shall I test instead?

Public API. Everything that is visible to the "outerworld". Which is in your case "Logged In !" and "Username or Password cann't be blank ".

Which results in 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');
 });

});



回答3:


Its simple to use, basically:-

spyOn(<name_of_the_object>, '<name_of_the_method>')

expect(<name_of_the_object>.<name_of_the_method>).toHaveBeenCalled();


来源:https://stackoverflow.com/questions/16787351/trying-to-understand-jasmines-tohavebeencalled-matcher

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!