Jasmine JavaScriptテスト-toBeとtoEqual


348

私が以下を持っているとしましょう:

var myNumber = 5;
expect(myNumber).toBe(5);
expect(myNumber).toEqual(5);

上記の両方のテストに合格します。数値の評価に関してtoBe()との違いはありtoEqual()ますか?もしそうなら、私はどちらを使うべきですか?


一言で言えば、プリミティブを比較するときに2つの間に違いはありません。オブジェクトの場合-> toEqual()キー/値-コンテンツで比較します。toBe()オブジェクト参照で比較します。
Andre Elrico

回答:


488

プリミティブ型(例えば番号、ブール値、文字列など)の場合は、差がないtoBeとはtoEqual。一つはのために働くのいずれか5trueまたは"the cake is a lie"

toBeとの違いを理解するために、toEqual3つのオブジェクトを想像してみましょう。

var a = { bar: 'baz' },
    b = { foo: a },
    c = { foo: a };

厳密な比較(===)を使用すると、いくつかは「同じ」です。

> b.foo.bar === c.foo.bar
true

> b.foo.bar === a.bar
true

> c.foo === b.foo
true

ただし、メモリ内の異なる場所に存在するオブジェクトを表すため、「等しい」としても「同じ」ではないものもあります。

> b === c
false

ジャスミンのtoBeマッチャーは厳密な等価比較のためのラッパーにすぎません

expect(c.foo).toBe(b.foo)

と同じです

expect(c.foo === b.foo).toBe(true)

ただ私の言葉を信じてはいけません。toBeのソースコードを参照してください。

しかしbc機能的に同等のオブジェクトを表します。彼らは両方のように見えます

{ foo: { bar: 'baz' } }

それが同じオブジェクトを表さなくても「等しい」bと言えるのでcはないでしょうか。

toEqual「deep equality」をチェックするを入力します(つまり、オブジェクトを再帰的に検索して、キーの値が等しいかどうかを判断します)。次の両方のテストに合格します。

expect(b).not.toBe(c);
expect(b).toEqual(c);

いくつかのことを明確にするのに役立つことを願っています。


17
「プリミティブ型(たとえば、数値、ブール値、文字列など)の場合、toBeとtoEqualの間に違いはありません」-これは完全に真実ではありません。expect(0).toBe(-0)合格しますが、expect(0).toEqual(-0)失敗します。
mgol 2017

11
tl; dr- toBe厳密な等価性をtoEqual使用します-参照で比較し、プロパティの等価性を使用します。toEqualプリミティブの使用をお勧めします
Drenai 2017

1
では、プリミティブにはどちらを使用すればよいのでしょうか。それはなぜですか。ドレナイ、なぜtoEqualを勧めるのですか?
Patrick Szalapski、

@PatrickSzalapski私だけDenaiの推理を推測することができますが、toEqual平等(約はるかに慎重である0 != -0"hi" = new String("hi")私が使用してお勧めしますので、など)をtoEqual 排他的にあなたが実際に参照等価性を懸念している場合を除き。すべてのチェックを参照してくださいtoEqualになりますeq:ここの方法github.com/jasmine/jasmine/blob/master/src/core/matchers/...

プリミティブを比較するときはtoBeを使用して、toEqualで行われるオーバーヘッドを節約する方が良いと思います。
GarfieldKlon

81

toBe()toEqual()toEqual()同等性をチェックします。toBe()一方、これらはまったく同じオブジェクトであることを確認します。

toBe()値を比較するときやtoEqual()、オブジェクトを比較するときに使用すると思います。

プリミティブ型を比較す​​るtoEqual()toBe()、同じ結果が得られます。オブジェクトを比較する場合、これtoBe()はより厳密な比較であり、メモリ内のまったく同じオブジェクトでない場合はfalseを返します。したがって、それがメモリ内のまったく同じオブジェクトであることを確認したくない場合を除き、toEqual()オブジェクトの比較に使用します。

詳細については、このリンクを確認してください:http : //evanhahn.com/how-do-i-jasmine/

ここで、数値toBe()との違いを見ると、toEqual()比較が正しい限り、違いはありません。5は常にと同等になり5ます。

さまざまな結果を確認するためにこれをいじるのに最適な場所はこちらです

更新

JavaScriptで何をするかを正確に理解することでtoBe()、簡単に確認toEqual()できます。Jasmine APIによると、ここにあります

toEqual()は単純なリテラルと変数に対して機能し、オブジェクトに対して機能するはずです

toBe()は ===

基本的にそれが言っていることtoEqual()toBe()同様のJavascripts ===演算子toBe()ですが、以下の例でも、それがまったく同じオブジェクトであることを確認してobjectOne === objectTwo //returns falseいます。ただし、toEqual()その場合はtrueを返します。

今、あなたは少なくとも与えられた理由を理解することができます:

var objectOne = {
    propertyOne: str,
    propertyTwo: num    
}

var objectTwo = {
    propertyOne: str,
    propertyTwo: num    
}

expect(objectOne).toBe(objectTwo); //returns false

これは、別の似たような質問に対するこの回答で述べたように===演算子は実際には、両方のオペランドが同じオブジェクトを参照するか、値型の場合は同じ値を持つことを意味します。


4
これは質問に答えることを避けます。同等性toEqual()toEqual()チェックすると言って何を説明するのですか?次の質問は明白ですが、「同等」とはどういう意味ですか?アルゴリズムの説明は、「等価」を決定するために使用される、または行動事例の少なくとも実施例toEqual()toBe()異なり、これはより有用レンダリングあろう。
Mark Amery 2015年

8
これは質問に答えないだけでなく、間違っています。 toEqualではなく、オブジェクト間の詳細な比較に使用する必要がありtoBeます。 jsfiddle.net/bBL9P/67
ロイドバンクス

3
人々が言っ​​ていることが正しいかどうかをテストすることに煩わされていないようです。toBeとtoEqualはどちらも厳密な比較のようです。それをテストしてください...それで私のテストではまだ違いを見つけていません。たとえば、var f = 1; var g = "1" expect(f == g).toEqual(true); // true expect(f).toEqual(g); // false expect(f).toBe(g); // false
user1809104

6
これは完全に間違っています。toEqualとはまったく同じはありません==
貧乳

6
上記のコメントを読んでください。expect(1).toEqual('1')失敗しますが、1 == '1'真です。toEqualとは何の関係もありません==。それはようなものだ===、それはバイ値の比較と同様の方法でオブジェクトを比較することを除いて。
貧困

33

ジャスミンgithubプロジェクトを引用すると、

expect(x).toEqual(y); オブジェクトまたはプリミティブxとyを比較し、それらが等しい場合は渡す

expect(x).toBe(y);オブジェクトまたはプリミティブxとyを比較し、それらが同じオブジェクトである場合は渡す


14

ジャスミンのソースコードを見ると、問題にさらに光が当てられます。

toBe非常に単純で、恒等/厳密等価演算子を使用します===

  function(actual, expected) {
    return {
      pass: actual === expected
    };
  }

toEqual一方、約150行の長であるなどのオブジェクトに組み込まれたために特別な処理がありStringNumberBooleanDateErrorElementRegExp。他のオブジェクトについては、プロパティを再帰的に比較します。

これは、等価演算子の動作とは大きく異なり==ます。例えば:

var simpleObject = {foo: 'bar'};
expect(simpleObject).toEqual({foo: 'bar'}); //true
simpleObject == {foo: 'bar'}; //false

var castableObject = {toString: function(){return 'bar'}};
expect(castableObject).toEqual('bar'); //false
castableObject == 'bar'; //true

2

toEqual()プリミティブの場合は値を比較し、オブジェクトの場合は内容を比較します。 toBe()参照を比較します。

次のコード/スイートは自明でなければなりません:

describe('Understanding toBe vs toEqual', () => {
  let obj1, obj2, obj3;

  beforeEach(() => {
    obj1 = {
      a: 1,
      b: 'some string',
      c: true
    };

    obj2 = {
      a: 1,
      b: 'some string',
      c: true
    };

    obj3 = obj1;
  });

  afterEach(() => {
    obj1 = null;
    obj2 = null;
    obj3 = null;
  });

  it('Obj1 === Obj2', () => {
    expect(obj1).toEqual(obj2);
  });

  it('Obj1 === Obj3', () => {
    expect(obj1).toEqual(obj3);
  });

  it('Obj1 !=> Obj2', () => {
    expect(obj1).not.toBe(obj2);
  });

  it('Obj1 ==> Obj3', () => {
    expect(obj1).toBe(obj3);
  });
});

1

誰かが(注釈付き)例による説明を好むかもしれないと思った:

以下では、私のdeepClone()関数が正しく機能していれば、テスト(「it()」呼び出しで説明)は成功します。

describe('deepClone() array copy', ()=>{
    let source:any = {}
    let clone:any = source
    beforeAll(()=>{
        source.a = [1,'string literal',{x:10, obj:{y:4}}]
        clone = Utils.deepClone(source) // THE CLONING ACT TO BE TESTED - lets see it it does it right.
    })
    it('should create a clone which has unique identity, but equal values as the source object',()=>{
        expect(source !== clone).toBe(true) // If we have different object instances...
        expect(source).not.toBe(clone) // <= synonymous to the above. Will fail if: you remove the '.not', and if: the two being compared are indeed different objects.
        expect(source).toEqual(clone) // ...that hold same values, all tests will succeed.
    })
})

もちろん、これは私のdeepClone()の完全なテストスイートではありません。これは、配列内のオブジェクトリテラル(およびその中にネストされているもの)も異なるIDで同じ値を持っている場合はここでテストしていません。


0

toEqualはディープイコールをチェックしていると思います。toBeは2つの変数の同じ参照です

  it('test me', () => {
    expect([] === []).toEqual(false) // true
    expect([] == []).toEqual(false) // true

    expect([]).toEqual([]); // true // deep check
    expect([]).toBe([]); // false
  })

-2

注意点:

  • toBe()比較をどのように扱うかObject.is()
  • toEqual()比較をどのように扱うか===

これがプリミティブ型の場合の理由であり、等価性をテストするときに大きな違いはtoBeありtoEqualませんが、オブジェクトなどの参照型の場合はtoEqual、等価性のテストに使用します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.