Jasmine JavaScript测试-toBe vs toEqual

Jasmine JavaScript测试-toBe vs toEqual,javascript,jasmine,Javascript,Jasmine,假设我有以下几点: var myNumber = 5; expect(myNumber).toBe(5); expect(myNumber).toEqual(5); 上述两项测试都将通过。在计算数字时,toBe()和toEqual()之间有区别吗?如果是这样,我什么时候应该使用一个而不是另一个?toBe()与toEqual():toEqual()检查等价性toBe(),确保它们是完全相同的对象 我会说,在比较值时使用toBe(),在比较对象时使用toEqual() 比较基元类型时,toEqua

假设我有以下几点:

var myNumber = 5;
expect(myNumber).toBe(5);
expect(myNumber).toEqual(5);
上述两项测试都将通过。在计算数字时,
toBe()
toEqual()
之间有区别吗?如果是这样,我什么时候应该使用一个而不是另一个?

toBe()
toEqual()
toEqual()
检查等价性<另一方面,code>toBe(),确保它们是完全相同的对象

我会说,在比较值时使用
toBe()
,在比较对象时使用
toEqual()

比较基元类型时,
toEqual()
toBe()
将产生相同的结果。在比较对象时,
toBe()
是一个更严格的比较,如果它不是内存中完全相同的对象,则返回false。因此,除非您想确保它与内存中的对象完全相同,否则请使用
toEqual()
来比较对象

有关更多信息,请查看此链接:

现在,在数字方面,看看
toBe()
toEqual()
之间的区别,只要比较正确,就不应该有任何区别<代码>5将始终等同于
5

一个很好的地方来玩这个,看看不同的结果是

更新 查看
toBe()
toEqual()
的一个简单方法是了解它们在JavaScript中的具体功能。根据Jasmine API,发现:

toEqual()适用于简单的文字和变量,也适用于对象

toBe()与
==

基本上,这是说
toEqual()
toBe()
是类似的Javascripts
==
操作符,除了
toBe()
也在检查以确保它是完全相同的对象,在下面的示例中
objectOne===objectTwo//也返回false
。但是,在这种情况下,
toEqual()
将返回true

现在,您至少可以理解为什么会出现以下情况:

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

var objectTwo = {
    propertyOne: str,
    propertyTwo: num    
}
expect(objectOne.toBe(objectTwo)//返回false


这是因为,正如
==
运算符中所述,实际上意味着两个操作数引用相同的对象,或者在值类型的情况下,具有相同的值。

引用jasmine github项目

expect(x)、toEqual(y)比较对象或基本体x和y以及
如果相等,则通过

expect(x)、toBe(y)比较对象或基本体x和y并传递
如果它们是同一对象

对于基本类型(例如数字、布尔值、字符串等),
toBe
toEqual
之间没有区别;任何一个都适用于
5
true
,或者
“蛋糕是谎言”

为了理解
toBe
toEqual
之间的区别,让我们想象三个对象

var a = { bar: 'baz' },
    b = { foo: a },
    c = { foo: a };
使用严格的比较(
=
),有些事情是“相同的”:

但有些东西,即使它们是“相等的”,也不是“相同的”,因为它们代表的是生活在记忆中不同位置的对象

> b === c
false
Jasmine的
toBe
matcher只不过是一个用于严格相等比较的包装器

expect(c.foo).toBe(b.foo)
是同一件事吗

expect(c.foo === b.foo).toBe(true)
不要只相信我的话;看

但是
b
c
表示功能等价的对象;他们看起来都像

{ foo: { bar: 'baz' } }
如果我们可以说
b
c
是“相等”的,即使它们不代表同一个对象,那不是很好吗

输入
toEqual
,检查“深度相等”(即通过对象进行递归搜索以确定其键的值是否相等)。以下两项测试都将通过:

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

希望这有助于澄清一些问题。

查看Jasmine源代码可以更清楚地了解这个问题

toBe
非常简单,只需使用标识/严格相等运算符,
==

  function(actual, expected) {
    return {
      pass: actual === expected
    };
  }
另一方面,
toEqual
,将近150行长,对内置对象有特殊处理,如
String
Number
Boolean
Date
Error
Element
RegExp
。对于其他对象,它递归地比较属性

这与等式运算符的行为非常不同,
=
。例如:

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

认为有人可能喜欢(注释)示例的解释:

下面,如果my 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.
    })
})
description('deepClone()数组副本',()=>{
让源:any={}
让克隆:any=源
以前(()=>{
source.a=[1,'stringliteral',{x:10,obj:{y:4}]
clone=Utils.deepClone(source)//要测试的克隆行为-让我们看看它是否正确。
})
它('应该创建一个具有唯一标识但与源对象具有相同值的克隆',()=>{
expect(source!==clone).toBe(true)//如果我们有不同的对象实例。。。
expect(source).not.toBe(clone)//
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);
  });
});

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

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

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

这就避免了回答问题。你可以解释
toEqual()
做了什么,说
toEqual()
检查等价性,但显而易见的下一个问题是可以的,“等价”是什么意思?对用于确定“等价性”的算法的描述,或者至少是
toEqual()行为的例子
toBe()
不同,这会使它更有用。这不仅不能回答问题,而且是错误的
  it('test me', () => {
    expect([] === []).toEqual(false) // true
    expect([] == []).toEqual(false) // true

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