toBe (จริง) vs toBeTruthy () vs toBeTrue ()


165

คือความแตกต่างระหว่างสิ่งที่expect(something).toBe(true), expect(something).toBeTruthy()และexpect(something).toBeTrue()?

ทราบว่าtoBeTrue()เป็นการจับคู่ที่กำหนดเองที่รู้จักในjasmine-matchersหมู่ matchers ที่มีประโยชน์และมีประโยชน์อื่น ๆ เช่นหรือtoHaveMethod()toBeArrayOfStrings()


คำถามนั้นมีความหมายทั่วไป แต่เป็นตัวอย่างจริงของโลกฉันกำลังทดสอบว่าองค์ประกอบนั้นแสดงprotractorขึ้นมา ฉันควรใช้ Matcher ประเภทใดในกรณีนี้

expect(elm.isDisplayed()).toBe(true);
expect(elm.isDisplayed()).toBeTruthy();
expect(elm.isDisplayed()).toBeTrue();

3
ฉันคิดว่า==.toBe(true) .toBeTrue()toBeTruthy () สามารถเป็นจริงได้ไม่เพียง แต่จะเป็นจริงแต่กับ123 , "dfgdfg", [1,2,3], ฯลฯ ... โดยพื้นฐานif(x==true)แล้วif(x===true)เป็นจริงในขณะที่เป็นจริง
dandavis


2
ซึ่งจะขึ้นอยู่กับค่าที่คุณทดสอบ ใช้toBeTruthyถ้าคุณไม่แน่ใจว่ามันเป็นแบบไหนใน== trueขณะที่ฉันสงสัยว่า.toBe(true)เป็นเหมือนกับ=== trueMind คุณจะรู้สึกเกินน้ำเล็กน้อยเพื่อเรียกใช้ฟังก์ชันเพื่อทดสอบความจริง คำแนะนำ, ลืม==และ!=มีอยู่ใน Javascript และอย่าใช้อีกครั้ง ความจริงไม่จำเป็นและเป็นกับดักสำหรับผู้เริ่มต้น ใช้===และ!==แทน
Blindman67

@ Blindman67 ขอบคุณสำหรับคำแนะนำมันสมเหตุสมผลดี เราได้มีeslintการรายงานเราถ้า==หรือ!=จะใช้บอกจะเปลี่ยนเป็นและ=== !==
alecxe

คำตอบ:


231

ฉันจะทำอย่างไรเมื่อฉันสงสัยว่าคำถามที่ถามที่นี่คือไปที่แหล่งที่มา

เป็น()

expect().toBe() หมายถึง:

function toBe() {
  return {
    compare: function(actual, expected) {
      return {
        pass: actual === expected
      };
    }
  };
}

มันทำการทดสอบด้วย===ซึ่งหมายความว่าเมื่อใช้เป็นexpect(foo).toBe(true)มันจะผ่านก็ต่อเมื่อfooมีค่าtrueจริง ค่าความจริงจะไม่ทำให้ผ่านการทดสอบ

toBeTruthy ()

expect().toBeTruthy() หมายถึง:

function toBeTruthy() {
  return {
    compare: function(actual) {
      return {
        pass: !!actual
      };
    }
  };
}

ประเภทการข่มขู่

ค่าคือ truthy trueถ้าการข่มขู่ของค่านี้เพื่อบูลที่มีอัตราผลตอบแทนคุ้มค่า การ!!ทดสอบการดำเนินงานสำหรับความจริงโดยการข่มขู่ค่าที่ส่งไปexpectยังบูลีน โปรดทราบว่าตรงกันข้ามกับสิ่งที่เป็นคำตอบที่ได้รับการยอมรับในปัจจุบันหมายถึง , == trueคือไม่ได้มีการทดสอบที่ถูกต้องสำหรับ truthiness คุณจะได้รับสิ่งที่ตลกเช่น

> "hello" == true
false
> "" == true
false
> [] == true
false
> [1, 2, 3] == true
false

ในขณะที่ใช้!!ผลผลิต:

> !!"hello"
true
> !!""
false
> !![1, 2, 3]
true
> !![] 
true

(ใช่ว่างเปล่าหรือไม่อาเรย์เป็นความจริง)

toBeTrue ()

expect().toBeTrue()เป็นส่วนหนึ่งของจัสมิน - แมทเทอร์ส (ซึ่งลงทะเบียนในเวลา 23.00 น. jasmine-expectหลังจากที่ลงทะเบียนjasmine-matchersครั้งแรกในภายหลัง)

expect().toBeTrue() หมายถึง:

function toBeTrue(actual) {
  return actual === true ||
    is(actual, 'Boolean') &&
    actual.valueOf();
}

ความแตกต่างกับexpect().toBeTrue()และexpect().toBe(true)คือexpect().toBeTrue()การทดสอบว่ามันคือการจัดการกับBooleanวัตถุ expect(new Boolean(true)).toBe(true)จะล้มเหลวในขณะที่expect(new Boolean(true)).toBeTrue()จะผ่าน นี่เป็นเพราะเรื่องตลกนี้:

> new Boolean(true) === true
false
> new Boolean(true) === false
false

อย่างน้อยมันก็เป็นความจริง:

> !!new Boolean(true)
true

อันไหนเหมาะที่สุดสำหรับใช้กับelem.isDisplayed()?

ในที่สุดไม้โปรแทรกเตอร์ได้ส่งคำขอนี้ไปยังซีลีเนียม เอกสารระบุว่ามูลค่าที่ผลิตโดยเป็นสัญญาที่แก้ไขไป.isDisplayed() booleanฉันจะเอามันที่มูลค่าและการใช้งานหรือ.toBeTrue() .toBe(true)หากฉันพบกรณีที่การใช้งานส่งคืนค่าความจริง / เท็จฉันจะยื่นรายงานข้อผิดพลาด


20

ในจาวาสคริปต์มีความจริงและความจริงอยู่ เมื่อบางสิ่งเป็นความจริงมันจะเห็นได้ชัดว่าเป็นจริงหรือเท็จ เมื่อสิ่งที่เป็นความจริงมันอาจหรือไม่อาจเป็นบูลีน แต่ค่า "โยน" ของเป็นบูลีน

ตัวอย่าง.

true == true; // (true) true
1 == true; // (true) truthy
"hello" == true;  // (true) truthy
[1, 2, 3] == true; // (true) truthy
[] == false; // (true) truthy
false == false; // (true) true
0 == false; // (true) truthy
"" == false; // (true) truthy
undefined == false; // (true) truthy
null == false; // (true) truthy

สิ่งนี้สามารถทำให้สิ่งต่าง ๆ ง่ายขึ้นถ้าคุณต้องการตรวจสอบว่ามีการตั้งค่าสตริงหรืออาร์เรย์มีค่าใด ๆ

var users = [];

if(users) {
  // this array is populated. do something with the array
}

var name = "";

if(!name) {
  // you forgot to enter your name!
}

และตามที่ระบุไว้ expect(something).toBe(true)และexpect(something).toBeTrue()เหมือนกัน แต่expect(something).toBeTruthy()ไม่เหมือนกันอย่างใดอย่างหนึ่ง


2
[] == false;ไม่ถูกต้องข้อความของตัวเองเป็นเท็จเพราะวัตถุมักจะเป็นความจริง
dandavis

@dandavis จับที่ดี
คา

@davavis ไม่จริง วัตถุไม่จริงเสมอไป แต่คำแถลง[] == false;นั้นคือtrue
คา

2
ไม่มันไม่มีประโยชน์ตรงข้ามกับความจริง: มันเป็น noob gotcha ... พิจารณา[""]==falseหรือ[0]== false; ไม่ว่างเปล่าไม่หลอกลวงหลอกลวงเพียง ...
dandavis

2
การใช้x == trueอย่างที่คุณมีในตัวอย่างของคุณเป็นสิ่งที่ทำให้เข้าใจผิดและดังที่ความเห็นด้านบนแสดงให้เห็นว่าวิธีที่ไม่ถูกต้องในการอธิบายแนวคิดเรื่องความเป็นจริงใน JavaScript การทดสอบความจริงที่แท้จริงใน JavaScript คือค่าที่ทำงานในifคำสั่งหรือเป็นตัวถูกดำเนินการในนิพจน์บูลีน เรารู้ว่า1เป็นความจริงเพราะif (1)จะทำให้คำสั่งต่อไปจะได้รับการประเมิน ในทำนองเดียวกัน[]ก็เป็นความจริงด้วยเหตุผลเดียวกัน: แม้ว่า[] == trueประเมินfalseแล้วif ([])ยังจะทำให้ข้อความต่อไปได้รับการประเมินดังนั้นเราจึงรู้ว่า[]เป็นความจริง
จอร์แดนวิ่ง

13

Disclamer : นี่เป็นเพียงการคาดเดา

ฉันรู้ว่าทุกคนชอบรายการที่อ่านง่าย:

  • toBe(<value>) - ค่าที่ส่งคืนเป็นเช่นเดียวกับ <value>
  • toBeTrue() - ตรวจสอบว่าค่าที่ส่งคืนเป็น true
  • toBeTruthy() - ตรวจสอบว่าค่าเมื่อนำไปบูลีนจะเป็นค่าจริงหรือไม่

    ค่า Truthy มีค่าทั้งหมดที่ไม่ได้0, ''(สตริงว่าง) false, null, NaN, undefinedหรือ[](อาร์เรย์ว่างเปล่า) *

    * สังเกตว่าเมื่อคุณเรียกใช้!![]มันจะกลับtrueมา แต่เมื่อคุณเรียกใช้[] == falseก็จะกลับtrueมา ขึ้นอยู่กับวิธีการนำไปใช้ ในคำอื่น ๆ :(!![]) === ([] == false)


ในตัวอย่างของคุณtoBe(true)และtoBeTrue()จะให้ผลลัพธ์เดียวกัน


อาร์เรย์ที่ว่างเปล่าเป็นเท็จ
คาห์

@MicahWilliamson ขอบคุณ! แก้ไขคำตอบ
Ismael Miguel

3
อาร์เรย์ว่างเป็นความจริง 100% ใน JSalert(!![])
dandavis

@dandavis ในคอนโซลของคุณผลิต[] == true ในคอนโซลของคุณผลิตfalse[] == falsetrue
มิคาห์

@MicahWilliamson: นั่นเป็นเพราะคุณกำลังเปรียบเทียบเวอร์ชันสตริงของอาร์เรย์ (สตริงว่าง) กับ True มันอาจสร้างความสับสน ...
dandavis

1

มีคำตอบที่ดีมากมายฉันอยากเพิ่มสถานการณ์ที่การใช้ความคาดหวังเหล่านี้อาจเป็นประโยชน์ ใช้element.all(xxx)ถ้าฉันต้องการตรวจสอบว่าองค์ประกอบทั้งหมดจะแสดงที่เรียกใช้ครั้งเดียวฉันสามารถดำเนินการ -

expect(element.all(xxx).isDisplayed()).toBeTruthy(); //Expectation passes
expect(element.all(xxx).isDisplayed()).toBe(true); //Expectation fails
expect(element.all(xxx).isDisplayed()).toBeTrue(); //Expectation fails

เหตุผลที่ถูก.all()ส่งกลับอาร์เรย์ของค่านิยมและอื่น ๆ ทุกชนิดของความคาดหวัง ( getText, isPresentฯลฯ ... ) สามารถดำเนินการกับtoBeTruthy()เมื่อ.all()เข้ามาในภาพ หวังว่านี่จะช่วยได้


ดี! ฉันจำได้ว่าreduce()การใช้ชุดบูลีนเป็นค่าเดียวจากนั้นจึงใช้การtoBe(true)ตรวจสอบ มันง่ายกว่านี้มากขอบคุณ
alecxe
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.