javascript 试图理解 Jasmine 的 toHaveBeenCalled() 匹配器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16787351/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 05:59:59  来源:igfitidea点击:

Trying to understand Jasmine's toHaveBeenCalled() matcher

javascriptunit-testingbddjasmine

提问by Ancient

I am new to jasminehere is my srcfile in which i create Authclass

我是新来的,jasmine这是我src在其中创建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 !";
    }
}

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

现在我想测试茉莉花的toHaveBeenCalled()匹配器。这是我写的

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

but it says that undefined() method does not exist

但它说 undefined() method does not exist

回答by basecode

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

查看您的用例,我不建议toHaveBeenCalled在此处使用。toHaveBeenCalled在您想要测试回调(异步)或与模拟结合的情况下很有用。

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

将内部发生的一切Auth.prototype.Login视为对“外部世界”不可见的实现细节。你不应该测试实现细节。这引发了两个问题。

Why shouldn't I test implementation details?

为什么我不应该测试实现细节?

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

它使重构变得困难。假设您Auth.prototype.isEmpty出于某些原因想将underscore.isEmpty. 几天后,您决定underscore完全替换为lodash。这将迫使您更改测试三次。将阻止您轻松重构的一切视为“禁止”。

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 ".

公共 API。对“外界”可见的一切。在您的情况下是“登录!” 和“用户名或密码不能为空”。

Which results in 3 tests:

这导致 3 个测试:

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

});

回答by Alberto Zaccagni

EDIT: Look at basecode answerfor a better approach

编辑:查看基本代码答案以获得更好的方法



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

从 docs,你应该像下面这样使用它:

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();
});

回答by prashantsahni

Its simple to use, basically:-

它易于使用,基本上:-

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

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