재스민 자바 스크립트 테스팅-ToBe vs toEqual


349

내가 다음을 가지고 있다고 가정 해 봅시다.

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

위의 두 가지 테스트를 모두 통과합니다. 숫자를 평가할 때 toBe()와 시간에 차이가 toEqual()있습니까? 그렇다면 다른 것을 사용하지 말아야 할 때?


간단히 말해서 : 프리미티브를 비교할 때 둘 사이에 차이가 없습니다. 객체의 경우-> toEqual()키 / 값-내용으로 비교합니다. toBe()객체 참조로 비교합니다.
Andre Elrico

답변:


489

기본 유형 (예 : 숫자, 부울, 문자열 등)의 경우 toBetoEqual; 사이에는 차이가 없습니다 . 둘 중 하나가 작동 할 것이다 5, true또는 "the cake is a lie".

의 차이를 이해하기 toBetoEqual,의 세 개의 객체를 가정 해 봅시다.

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

Jasmine의 toBematcher는 엄격한 평등 비교를위한 래퍼에 지나지 않습니다.

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

와 같은

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

단지 내 말을 받아들이지 마라. toBe의 소스 코드를 참조하십시오 .

그러나 bc기능이 동일한 개체를 나타냅니다; 그들은 둘 다처럼 보인다

{ foo: { bar: 'baz' } }

우리가 그렇게 말할 수 b있고 c그들이 같은 대상을 나타내지 않더라도 "동일"하다면 좋지 않습니까?

toEqual"deep equality"를 확인하는 Enter 키 (즉, 키 값이 동일한 지 여부를 판별하기 위해 오브젝트를 재귀 적으로 검색 함) 다음 두 가지 테스트를 모두 통과합니다.

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

그것이 어떤 것들을 분명히하는 데 도움이되기를 바랍니다.


17
"프리미티브 유형 (예 : 숫자, 부울, 문자열 등)의 경우 toBe와 toEqual 사이에는 차이가 없습니다. 이는 전적으로 사실이 아님으로 밝혀졌습니다. expect(0).toBe(-0)통과하지만 expect(0).toEqual(-0)실패합니다.
mgol

11
tl; dr- toBe엄격한 동등성을 사용합니다-참조로 비교하고 toEqual속성 동등성을 사용합니다. toEqual프리미티브 에 사용하도록 권장
Drenai

1
그래서 우리는 프리미티브에 어떤 것을 사용해야합니까? 왜 그렇습니까? 드레나이, 왜 평등을 추천합니까?
Patrick Szalapski

@PatrickSzalapski 난 단지 Denai의 추론에서 추측 할 수 있지만, toEqual평등 (약 훨씬 더 조심 0 != -0, "hi" = new String("hi")내가 사용하는 것이 좋습니다 것, 그래서 등)에 toEqual 독점적으로 실제로 참조 동등성에 대해 우려하지 않는 한. 모든 검사를 참조하십시오 toEqual에 있습니다 eq: 여기 방법 github.com/jasmine/jasmine/blob/master/src/core/matchers/...

프리미티브를 비교할 때 toEqual에서 수행되는 오버 헤드를 절약 할 때 toBe를 사용하는 것이 좋습니다.
GarfieldKlon

81

toBe()vs toEqual(): toEqual()동등성을 확인합니다. toBe()반면에, 그것들이 정확히 같은 객체인지 확인하십시오.

toBe()값을 toEqual()비교할 때 와 객체를 비교할 때 사용한다고 말하고 싶습니다 .

경우 기본 유형을 비교 toEqual()하고 toBe()동일한 결과를 산출 할 것이다. 객체를 비교할 때 toBe()더 엄격하게 비교하며 메모리에서 정확히 동일한 객체가 아닌 경우 false를 반환합니다. 따라서 메모리에서 정확히 동일한 객체인지 확인하지 않는 한 객체 toEqual()비교에 사용하십시오 .

자세한 정보는이 링크를 확인하십시오 : http://evanhahn.com/how-do-i-jasmine/

이제 숫자 toBe()와 의 차이점을 살펴볼 toEqual()때 비교가 정확하다면 차이가 없어야합니다. 5항상와 같습니다 5.

다른 결과를보기 위해 이것을 가지고 놀기에 좋은 곳이 여기 있습니다

최신 정보

보는 쉬운 방법 toBe()toEqual()그들이 자바 스크립트에서 할 정확히 이해하는 것입니다. Jasmine API에 따르면 다음 위치 에서 찾을 수 있습니다 .

toEqual ()은 간단한 리터럴 및 변수에 대해 작동하며 객체에 대해 작동해야합니다.

toBe ()는 ===

이다 말하는 것을 본질적으로 무엇 toEqual()toBe()유사한 Javascript를에있는 ===제외 운영자 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

8
이 질문에 대한 답변뿐만 아니라 잘못되었습니다 . toEqual아닌 객체 간 심도있는 비교에 사용해야합니다 toBe. jsfiddle.net/bBL9P/67
Lloyd Banks

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전혀 동일 하지 않습니다== .
meagar

6
위의 의견을 읽으십시오. expect(1).toEqual('1')실패하지만 1 == '1'사실입니다. toEqual와는 아무런 관련이 없습니다 ==. 값별 ===비교와 비슷한 방식으로 객체를 비교한다는 점을 제외하면 같습니다 .
meagar

33

자스민 github 프로젝트를 인용하자면,

expect(x).toEqual(y); 객체 또는 프리미티브 x와 y를 비교하고 동일한 경우 전달합니다.

expect(x).toBe(y);객체 또는 프리미티브 x와 y를 비교 하고 동일한 객체 인 경우 전달


14

Jasmine 소스 코드를 보면이 문제에 대해 더 많은 정보를 얻을 수 있습니다.

toBe매우 간단하고 ID / 엄격한 동등 연산자를 사용합니다 ===.

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

toEqual반면에, 거의 150 선 길이와 같은 객체에 내장 된 특별한 취급을 가지고 String, Number, Boolean, Date, Error, ElementRegExp. 다른 객체의 경우 속성을 재귀 적으로 비교합니다.

이것은 항등 연산자의 동작과 매우 다릅니다 ==. 예를 들면 다음과 같습니다.

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.
    })
})

물론 이것은 배열의 객체 리터럴 (및 그 안에 중첩 된 객체)이 고유 한 ID이지만 동일한 값을 갖는 경우 여기에서 테스트하지 않았으므로 이것은 deepClone ()에 대한 완전한 테스트 스위트가 아닙니다.


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()비교를 어떻게 처리합니다 ===.

그의 이유 원시 유형, toBetoEqual어떤지를 테스트 할 때 큰 차이가 없지만 객체와 같은 참조 유형의 경우, 오히려 사용하게 될 것 toEqual어떤지를 테스트합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.