Chai: วิธีทดสอบ undefined ด้วยไวยากรณ์ 'should'


96

จากบทช่วยสอนนี้ทดสอบแอป angularjs กับ chai ฉันต้องการเพิ่มการทดสอบสำหรับค่าที่ไม่ได้กำหนดโดยใช้สไตล์ "should" สิ่งนี้ล้มเหลว:

it ('cannot play outside the board', function() {
  scope.play(10).should.be.undefined;
});

มีข้อผิดพลาด "TypeError: ไม่สามารถอ่านคุณสมบัติ" should "ของ undefined" แต่การทดสอบผ่านไปด้วยลักษณะ "คาดหวัง":

it ('cannot play outside the board', function() {
  chai.expect(scope.play(10)).to.be.undefined;
});

ฉันจะทำให้มันทำงานร่วมกับ "ควร" ได้อย่างไร


1
เป็นเรื่องง่ายถ้าคุณจะใช้ "ยืนยัน" คุณสามารถทำได้assert.isUndefined(scope.play(10))
lukaserat

คำตอบ:


80

นี่เป็นข้อเสียอย่างหนึ่งของไวยากรณ์ควร มันทำงานโดยการเพิ่มคุณสมบัติ should ให้กับออบเจ็กต์ทั้งหมด แต่ถ้าไม่ได้กำหนดค่าส่งคืนหรือค่าตัวแปรแสดงว่าไม่มีวัตถุที่จะเก็บคุณสมบัติไว้

เอกสารช่วยให้การแก้ไขปัญหาบางอย่างเช่น:

var should = require('chai').should();
db.get(1234, function (err, doc) {
  should.not.exist(err);
  should.exist(doc);
  doc.should.be.an('object');
});

15
should.not.existจะตรวจสอบว่าค่าเป็นnullดังนั้นคำตอบนี้ไม่ถูกต้อง @daniel มีคำตอบด้านล่าง: should.equal(testedValue, undefined);. นั่นควรเป็นคำตอบที่ได้รับการยอมรับ
Sebastian

7
ฉันได้รับคำตอบนี้ (ไม่ใช่เอกสาร🙈) เป็นประจำทุกเดือน :-)
Ralph Cowling

54
should.equal(testedValue, undefined);

ตามที่กล่าวไว้ในเอกสารชัย


12
omg มีอะไรจะอธิบาย? คุณคาดว่าจะทดสอบค่าเป็น === ไม่ได้กำหนดดังนั้นคุณจึงทดสอบ นักพัฒนาหลายคนใส่ TestValue เป็นอันดับแรกก่อนจากนั้นจึงเชื่อมต่อด้วย should และมันก็จบลงด้วยข้อผิดพลาด ...
daniel

5
นี้ไม่ได้ทำงานออกจากกล่องและจะไม่พบในเอกสาร API .equal()สำหรับ ฉันเข้าใจว่าทำไม @OurManInBananas จึงขอคำอธิบาย เป็นการใช้งานที่ไม่คาดคิดเป็นฟังก์ชันที่ยอมรับสองอาร์กิวเมนต์แทนที่จะเป็นรูปแบบวิธีการผูกมัดที่คาดไว้ซึ่งยอมรับอาร์กิวเมนต์เดียวสำหรับค่าที่คาดไว้ คุณสามารถทำได้โดยการนำเข้า / กำหนดและกำหนดเวอร์ชันที่เรียกใช้.should()ตามที่อธิบายไว้ในคำตอบที่ยอมรับโดย @DavidNorman และในเอกสารนี้
gfullam

ฉันคิดว่าคุณจะพบว่า.equalไวยากรณ์นั้นสร้างข้อความแสดงข้อผิดพลาดที่ดีกว่ามากเพราะช่วยให้คุณสามารถส่งออกข้อความที่อธิบายได้มากขึ้นเมื่อสิ่งต่างๆล้มเหลว
jcollum

17

ทดสอบไม่ได้กำหนด

var should = require('should');
...
should(scope.play(10)).be.undefined;

ทดสอบค่าว่าง

var should = require('should');
...
should(scope.play(10)).be.null;

ทดสอบความเท็จเช่นถือว่าเป็นเท็จในเงื่อนไข

var should = require('should');
...
should(scope.play(10)).not.be.ok;

ไม่มีประโยชน์เป็นพิเศษหรือใช้งานง่าย แต่ฉลาด!
thebenedict

2
ไม่มีประโยชน์? เป็นคำตอบที่ดีที่สุดสำหรับการทดสอบที่ไม่ได้กำหนดใน IMO สไตล์ bdd แต่ต้องติดตั้งแพ็คเกจ npm อื่น ๆ (ควรเป็นแพ็คเกจ) และฉันไม่คิดว่าจะคุ้มค่ากับการติดตั้งแพ็คเกจอื่นเพียงแค่นั้นคำตอบที่ยอดเยี่ยม
Wagner Leonardi


8

ฉันพยายามเขียนคำสั่ง should สำหรับการทดสอบที่ไม่ได้กำหนด สิ่งต่อไปนี้ใช้ไม่ได้

target.should.be.undefined();

ฉันพบวิธีแก้ไขปัญหาต่อไปนี้

(target === undefined).should.be.true()

หากสามารถเขียนเป็นเช็คประเภทได้

(typeof target).should.be.equal('undefined');

ไม่แน่ใจว่าข้างต้นเป็นวิธีที่ถูกต้องหรือไม่ แต่ได้ผล

อ้างอิงจากโพสต์จาก ghost ใน github


1
เป็นที่น่าสังเกตว่าการใช้ไวยากรณ์นี้อาจส่งผลให้ JavaScript ตีความนิพจน์ในวงเล็บเป็นการพยายามเรียกบรรทัดก่อนหน้าเป็นฟังก์ชัน (หากคุณไม่ได้ลงท้ายบรรทัดด้วยอัฒภาค)
bmacnaughton

5

ลองสิ่งนี้:

it ('cannot play outside the board', function() {
   expect(scope.play(10)).to.be.undefined; // undefined
   expect(scope.play(10)).to.not.be.undefined; // or not
});

ขอบคุณ แต่นั่นคือสิ่งที่ฉันกำลังทำในความพยายามครั้งที่สองข้างต้น ฉันต้องการเข้าใจวิธีการใช้ไวยากรณ์ควร
thebenedict

2

อย่าลืมเกี่ยวกับชุดค่าผสมhaveและnotคำหลัก:

const chai = require('chai');
chai.should();
// ...
userData.should.not.have.property('passwordHash');

1

คำตอบโดย @ david-norman ถูกต้องตามเอกสารฉันมีปัญหาเล็กน้อยในการตั้งค่าและเลือกใช้สิ่งต่อไปนี้แทน

(typeof scope.play (10)). should.be.undefined;


typeofผู้ประกอบการส่งกลับสตริง ; ดังนั้นจึงไม่สามารถผ่านการยืนยันนี้ได้ cuz'undefined' !== undefined
dNitro

0

คุณสามารถรวมผลการทำงานของคุณshould()และทดสอบประเภท "ไม่ได้กำหนด":

it ('cannot play outside the board', function() {
  should(scope.play(10)).be.type('undefined');
});
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.