假设我有以下内容:
var myNumber = 5;
expect(myNumber).toBe(5);
expect(myNumber).toEqual(5);
以上两个测试都将通过。在计算数字时,toBe()和toEqual()之间有区别吗?如果是的话,什么时候我应该使用其中一种而不是另一种?
假设我有以下内容:
var myNumber = 5;
expect(myNumber).toBe(5);
expect(myNumber).toEqual(5);
以上两个测试都将通过。在计算数字时,toBe()和toEqual()之间有区别吗?如果是的话,什么时候我应该使用其中一种而不是另一种?
当前回答
我想有人可能会喜欢用(注释的)例子来解释:
下面,如果我的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()的完整测试套件,因为我没有在这里测试数组中的对象文字(以及其中嵌套的对象)是否也具有不同的标识但相同的值。
其他回答
我认为toEqual是检查deep equal, toBe是2个变量的相同引用
it('test me', () => {
expect([] === []).toEqual(false) // true
expect([] == []).toEqual(false) // true
expect([]).toEqual([]); // true // deep check
expect([]).toBe([]); // false
})
查看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
引用jasmine github项目,
期望(x) .toEqual (y);比较对象或原语x和y和 如果它们相等,则通过 期望(x) .toBe (y);比较对象或原语x和y并传递 如果它们是同一个物体
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);
});
});
我想有人可能会喜欢用(注释的)例子来解释:
下面,如果我的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()的完整测试套件,因为我没有在这里测试数组中的对象文字(以及其中嵌套的对象)是否也具有不同的标识但相同的值。