Jasmine JavaScript 测试 - toBe vs toEqual

IT技术 javascript jasmine
2021-02-16 22:23:48

假设我有以下内容:

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

以上两个测试都会通过。有没有之间的差异toBe(),并toEqual()当它涉及到评估的数字?如果是这样,我什么时候应该使用一个而不是另一个?

6个回答

对于原始类型(例如数字、布尔值、字符串等),toBe之间没有区别toEqual任何一个可以为工作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匹配器只不过是一个严格相等比较的包装器

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

是一样的

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

不要只相信我的话;查看toBe 的源代码

但是bc代表功能等效的对象;他们俩看起来都像

{ foo: { bar: 'baz' } }

如果我们可以这样说b并且c即使它们不代表同一个对象也“相等” ,那不是很好吗?

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

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

希望这有助于澄清一些事情。

tl;dr -toBe使用严格相等 - 通过引用比较,toEqual使用属性等价。推荐toEqual用于基元
2021-04-21 22:23:48
那么我们应该为基元使用哪一个,为什么?Drenai,你为什么推荐toEqual?
2021-05-04 22:23:48
@PatrickSzalapski我只能猜测德纳在的推理,但toEqual更加谨慎平等(0 != -0"hi" = new String("hi"),等),所以我建议使用toEqual 专门除非你真的关心引用等价。toEqualeq此处查看方法中的所有检查github.com/jasmine/jasmine/blob/master/src/core/matchers/...
2021-05-10 22:23:48
我认为在比较原语时最好使用 toBe 来节省在 toEqual 中完成的开销。
2021-05-11 22:23:48
“对于原始类型(例如数字、布尔值、字符串等),toBe 和 toEqual 之间没有区别”——事实证明这并不完全正确。expect(0).toBe(-0)会通过,但expect(0).toEqual(-0)会失败。
2021-05-16 22:23:48

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()是了解他们在JavaScript中做什么。根据 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

这是因为,在说明这个答案不同,但类似的问题,===运营商实际上意味着两个操作数引用同一个对象,或在值类型的情况下,具有相同的值。

这是完全错误的。toEqual完全不同==
2021-04-17 22:23:48
人们似乎并不愿意测试他们所说的是否正确。toBe 和 toEqual 似乎都是严格的比较。测试一下......所以在我的测试中我还没有发现区别。例如:var f = 1; var g = "1" expect(f == g).toEqual(true);//true expect(f).toEqual(g);//false expect(f).toBe(g);//false
2021-04-28 22:23:48
阅读上面的评论。expect(1).toEqual('1')失败,而1 == '1'为真。toEqual与 无关==这就像===除了它会以类似于按值比较的方式比较对象。
2021-05-01 22:23:48
这不仅没有回答问题,而且是错误的toEqual应该用于对象之间的深入比较,而不是toBe. jsfiddle.net/bBL9P/67
2021-05-04 22:23:48
这避免了回答问题。toEqual()通过说toEqual()检查等效来解释什么,但显然下一个问题是可以的,那么“等效”是什么意思?用于确定“等效性”的算法的描述,或者至少是toEqual()的行为toBe()不同的情况的示例,将使这更有用。
2021-05-06 22:23:48

引用jasmine github项目,

expect(x).toEqual(y); 比较对象或基元 x 和 y,如果它们相等则通过

expect(x).toBe(y);比较对象或基元 x 和 y, 如果它们是同一个对象,则通过

查看 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

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