web-dev-qa-db-ja.com

ジャスミンのtoHaveBeenCalled()マッチャーを理解しようとしています

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

今、私はジャスミンのtoHaveBeenCalled()マッチャーをテストしたいと思います。これが私が書いたものです

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

しかし、それはundefined() method does not existと言っています

14
Ancient

編集:より良いアプローチについては basecode answer を見てください


ドキュメントから 、次のように使用する必要があります。

spyOn(foo, 'setBar');

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

だからあなたは書くべきです:

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

ユースケースを見ると、ここでtoHaveBeenCalledを使用することはお勧めできません。 toHaveBeenCalledは、テストコールバック(非同期)またはモックと組み合わせたい場合に便利です。

Auth.prototype.Login内で発生するすべてのことを、「外界」からは見えない実装の詳細と見なします。実装の詳細はテストしないでください。これは2つの質問を引き起こします。

実装の詳細をテストすべきではないのはなぜですか?

リファクタリングが難しくなります。何らかの理由でAuth.prototype.isEmptyunderscore.isEmptyに置き換えたいとします。数日後、underscoreを完全にlodashに置き換えることにしました。これにより、テストを3回変更する必要があります。リファクタリングを簡単に妨げるすべてのものを「ノーゴー」と見なしてください。

代わりに何をテストしますか?

パブリックAPI。 「外の世界」に見えるすべてのもの。あなたの場合は「ログイン!」です。および「ユーザー名またはパスワードを空白にすることはできません」。

その結果、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');
 });

});
24
basecode

基本的にその使い方は簡単です:-

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

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