สมมติว่าฉันมีดังต่อไปนี้:
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()
เมื่อมันมาถึงการประเมินตัวเลข? ถ้าเป็นเช่นนั้นฉันควรใช้อันใดอันหนึ่ง
คำตอบ:
สำหรับประเภทดั้งเดิม (เช่นตัวเลขบูลีนสตริง ฯลฯ ) ไม่มีความแตกต่างระหว่างtoBe
และtoEqual
; คนใดคนหนึ่งจะทำงานให้5
, หรือtrue
"the cake is a lie"
เพื่อให้เข้าใจถึงความแตกต่างระหว่างtoBe
และtoEqual
ลองจินตนาการถึงวัตถุสามชิ้น
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
ผู้toBe
จับคู่ของจัสมินไม่มีอะไรมากไปกว่าเสื้อคลุมสำหรับการเปรียบเทียบความเท่าเทียม
expect(c.foo).toBe(b.foo)
เป็นสิ่งเดียวกัน
expect(c.foo === b.foo).toBe(true)
อย่าเพิ่งเชื่อฟังคำของฉัน ดูซอร์สโค้ดสำหรับ Tobe
แต่b
และc
แสดงวัตถุที่เทียบเท่ากับการใช้งานได้ พวกเขาทั้งสองดูเหมือน
{ foo: { bar: 'baz' } }
มันจะไม่ดีถ้าเราสามารถพูดได้b
และc
เป็น "เท่ากัน" แม้ว่าพวกเขาจะไม่ได้เป็นตัวแทนของวัตถุเดียวกันหรือไม่?
ใส่toEqual
ซึ่งจะตรวจสอบ "ความเท่าเทียมกันลึก" (เช่นการค้นหาซ้ำผ่านวัตถุเพื่อตรวจสอบว่าค่าสำหรับคีย์ของพวกเขาจะเทียบเท่า) ทั้งการทดสอบต่อไปนี้จะผ่าน:
expect(b).not.toBe(c);
expect(b).toEqual(c);
หวังว่าจะช่วยชี้แจงบางสิ่ง
expect(0).toBe(-0)
จะผ่าน แต่expect(0).toEqual(-0)
จะล้มเหลว
toBe
ใช้ความเท่าเทียมกันที่เข้มงวด - เปรียบเทียบโดยการอ้างอิงtoEqual
ใช้การเทียบเท่าคุณสมบัติ แนะนำให้ใช้toEqual
สำหรับดึกดำบรรพ์
toEqual
เป็นความระมัดระวังมากขึ้นเกี่ยวกับความเท่าเทียมกัน ( 0 != -0
, "hi" = new String("hi")
ฯลฯ ) ดังนั้นผมจึงขอแนะนำให้ใช้toEqual
เฉพาะถ้าคุณกำลังกังวลเกี่ยวกับความเท่าเทียมกันจริงอ้างอิง ดูการตรวจสอบทั้งหมดที่toEqual
ทำในeq
วิธีการที่นี่: github.com/jasmine/jasmine/blob/master/src/core/matchers/…
toBe()
กับtoEqual()
: toEqual()
ตรวจสอบความเท่าเทียมกัน toBe()
ในทางกลับกันตรวจสอบให้แน่ใจว่าพวกเขาเป็นวัตถุเดียวกันแน่นอน
ฉันจะบอกว่าใช้toBe()
เมื่อเปรียบเทียบค่าและtoEqual()
เมื่อเปรียบเทียบวัตถุ
เมื่อเปรียบเทียบประเภทดั้งเดิมtoEqual()
และtoBe()
จะให้ผลลัพธ์เดียวกัน เมื่อเปรียบเทียบวัตถุtoBe()
คือการเปรียบเทียบที่เข้มงวดยิ่งขึ้นและหากไม่ใช่วัตถุเดียวกันที่แน่นอนในหน่วยความจำสิ่งนี้จะส่งคืนค่าเท็จ ดังนั้นหากคุณไม่ต้องการให้แน่ใจว่าเป็นวัตถุเดียวกันในหน่วยความจำให้ใช้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()
จะกลับมาจริงในสถานการณ์นั้น
อย่างน้อยตอนนี้คุณสามารถเข้าใจว่าทำไมเมื่อได้รับ:
var objectOne = {
propertyOne: str,
propertyTwo: num
}
var objectTwo = {
propertyOne: str,
propertyTwo: num
}
expect(objectOne).toBe(objectTwo); //returns false
นั่นเป็นเพราะตามที่ระบุไว้ในคำตอบนี้กับคำถามที่แตกต่างกัน แต่คำถามที่คล้ายกันตัว===
ดำเนินการจริงหมายถึงว่าตัวถูกดำเนินการทั้งสองอ้างถึงวัตถุเดียวกันหรือในกรณีของประเภทค่ามีค่าเท่ากัน
toEqual()
โดยบอกว่าtoEqual()
ตรวจสอบความเท่าเทียมกันแต่คำถามต่อไปที่เห็นได้ชัดก็โอเคดังนั้น "เทียบเท่า" หมายถึงอะไร คำอธิบายของอัลกอริทึมที่ใช้ในการกำหนด "ความเท่าเทียมกัน" หรืออย่างน้อยตัวอย่างของกรณีที่พฤติกรรมของtoEqual()
และtoBe()
แตกต่างกันจะทำให้มีประโยชน์มากขึ้น
toEqual
jsfiddle.net/bBL9P/67toBe
toEqual
คือไม่ได้เลย==
เช่นเดียวกับ
expect(1).toEqual('1')
ล้มเหลวในขณะที่1 == '1'
เป็นจริง มีอะไรจะทำอย่างไรกับtoEqual
==
มันเหมือนกับ===
ว่ามันจะเปรียบเทียบวัตถุในลักษณะที่คล้ายคลึงกับการเปรียบเทียบตามค่า
เพื่ออ้างถึงโครงการดอกมะลิ Github
expect(x).toEqual(y);
เปรียบเทียบออบเจ็กต์หรือค่าพื้นฐาน x และ y และผ่านถ้ามันเทียบเท่ากัน
expect(x).toBe(y);
เปรียบเทียบออบเจ็กต์หรือค่าพื้นฐาน x และ y และผ่าน หากเป็นวัตถุเดียวกัน
การดูรหัสที่มาของจัสมินทำให้เกิดปัญหามากขึ้น
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
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 () ของฉันเนื่องจากฉันยังไม่ได้ทดสอบที่นี่หากออบเจ็กต์ตัวอักษรในอาเรย์
ฉันคิดว่า toqual กำลังตรวจสอบความลึกเท่ากับ, toBe เป็นการอ้างอิงเดียวกันของตัวแปร 2 ตัว
it('test me', () => {
expect([] === []).toEqual(false) // true
expect([] == []).toEqual(false) // true
expect([]).toEqual([]); // true // deep check
expect([]).toBe([]); // false
})
จุดที่ควรทราบ:
toBe()
การเปรียบเทียบการปฏิบัติเช่นวิธีการObject.is()
ทำtoEqual()
การเปรียบเทียบการปฏิบัติเช่นวิธีการ===
ทำนั่นเป็นเหตุผลสำหรับประเภทดั้งเดิมtoBe
และtoEqual
ไม่มีความแตกต่างกันมากนักเมื่อทำการทดสอบความเสมอภาค แต่สำหรับประเภทการอ้างอิงเช่นวัตถุคุณควรใช้toEqual
เพื่อทดสอบความเท่าเทียมกัน
toEqual()
จะเปรียบเทียบโดยคีย์ / ค่าเนื้อหาtoBe()
จะเปรียบเทียบโดยการอ้างอิงวัตถุ