Jasmine JavaScript测试-成为与等于

kb5ga3dv  于 2022-12-25  发布在  Java
关注(0)|答案(7)|浏览(116)

假设我有以下内容:

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

上述两个测试都将通过。在计算数字时,toBe()toEqual()之间有区别吗?如果有,什么时候应该使用其中一个而不是另一个?

swvgeqrz

swvgeqrz1#

对于原语类型(例如数字、布尔值、字符串等),toBetoEqual之间没有区别;任何一个都将对5true"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的toBe匹配器只不过是一个用于严格相等比较的 Package 器

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

是一回事

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

不要只相信我的话参见the source code for toBe
但是bc表示功能上等效的对象;他们看起来都像

{ foo: { bar: 'baz' } }

如果我们可以说bc是"相等的",即使它们不表示同一个对象,那不是很好吗?
输入toEqual,检查"深度相等"(即递归搜索对象以确定其键的值是否相等)。以下两个测试都将通过:

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

zlhcx6iw2#

toBe()toEqual()toEqual()检查等价性。另一方面,toBe()确保它们是完全相同的对象。
我建议在比较值时使用toBe(),在比较对象时使用toEqual()
当比较基元类型时,toEqual()toBe()将产生相同的结果。当比较对象时,toBe()是一个更严格的比较,如果它不是内存中完全相同的对象,则将返回false。因此,除非您想确保它是内存中完全相同的对象,否则请使用toEqual()来比较对象。
查看此链接了解更多信息:http://evanhahn.com/how-do-i-jasmine/
现在,当谈到toBe()toEqual()之间的数字差异时,只要比较正确,就不应该有任何差异。5将始终等于5
here是一个很好的地方,可以尝试使用它来查看不同的结果

更新

了解toBe()toEqual()的一个简单方法是了解它们在JavaScript中的具体功能。根据Jasmine API,找到了here
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
这是因为,如this answer to a different, but similar question,中所述,===操作符实际上意味着两个操作数引用同一个对象,或者在值类型的情况下,具有相同的值。

mccptt67

mccptt673#

引用jasmine github项目的话,
expect(x).toEqual(y);比较对象或基元x和y,如果相等则通过
expect(x).toBe(y);比较对象或基元x和y,如果它们是同一对象,则传递***

4urapxun

4urapxun4#

查看Jasmine源代码可以更好地了解这个问题。
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
f8rj6qna

f8rj6qna5#

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

w51jfk4q6#

我认为toEqual是检查深度相等,toBe是2个变量的相同引用

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

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

46qrfjad7#

我想有人可能会喜欢通过(注解)示例进行解释:
下面,如果我的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()的完整测试套件,因为我还没有测试数组中的对象文字(以及嵌套在其中的对象文字)是否也具有不同的标识但具有相同的值。

相关问题