toBe (true) vs toBeTruthy () vs toBeTrue ()

165

Apa perbedaan antara expect(something).toBe(true), expect(something).toBeTruthy()dan expect(something).toBeTrue()?

Perhatikan bahwa toBeTrue()adalah matcher kustom diperkenalkan di jasmine-matchersantara matchers lain yang bermanfaat dan berguna seperti toHaveMethod()atau toBeArrayOfStrings().


Pertanyaannya dimaksudkan untuk menjadi generik, tetapi, sebagai contoh dunia nyata, saya menguji apakah suatu elemen ditampilkan protractor. Matcher mana yang harus saya gunakan dalam kasus ini?

expect(elm.isDisplayed()).toBe(true);
expect(elm.isDisplayed()).toBeTruthy();
expect(elm.isDisplayed()).toBeTrue();
alecxe
sumber
3
saya pikir .toBe(true)== .toBeTrue(). toBeTruthy () bisa benar tidak hanya pada benar , tetapi pada 123 , "dfgdfg", [1,2,3], dll ... pada dasarnya if(x==true)adalah kebenaran, sementara if(x===true)itu benar benar.
Dandavis
2
Ini mungkin membantu
ODelibalta
2
Itu akan tergantung pada apa nilai yang Anda uji. Gunakan toBeTruthyjika Anda tidak yakin dengan tipe itu sama seperti == truesementara saya curiga .toBe(true)sama dengan === trueMind Anda sedikit berlebihan untuk memanggil fungsi untuk menguji benar. Kata nasihat, Lupakan ==dan !=ada di Javascript dan jangan pernah menggunakannya lagi. Kebenaran tidak dibutuhkan dan perangkap untuk pemula. Gunakan ===dan !==sebagai gantinya.
Blindman67
@ Blindman67 terima kasih atas sarannya, sangat masuk akal. Kami bahkan telah eslintmelaporkan kami jika ==atau !=digunakan menyarankan untuk mengubahnya ke ===dan !==.
alecxe

Jawaban:

231

Apa yang saya lakukan ketika saya bertanya-tanya sesuatu seperti pertanyaan yang diajukan di sini adalah pergi ke sumbernya.

menjadi()

expect().toBe() didefinisikan sebagai:

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

Itu melakukan tes dengan ===yang berarti bahwa ketika digunakan sebagai expect(foo).toBe(true), itu akan berlalu hanya jika foobenar-benar memiliki nilai true. Nilai kebenaran tidak akan lulus uji.

toBeTruthy ()

expect().toBeTruthy() didefinisikan sebagai:

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

Ketik paksaan

Nilai benar jika paksaan dari nilai ini ke boolean menghasilkan nilai true. Operasi !!menguji kebenaran dengan memaksa nilai yang diteruskan ke expectboolean. Perhatikan bahwa sebaliknya untuk apa jawaban yang diterima saat ini menyiratkan , == trueadalah tidak tes yang benar untuk truthiness. Anda akan mendapatkan hal-hal lucu seperti

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

Sedangkan menggunakan !!hasil:

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

(Ya, kosong atau tidak, array itu benar.)

toBeTrue ()

expect().toBeTrue()adalah bagian dari Jasmine-Matchers (yang didaftarkan pada npm seperti jasmine-expectsetelah proyek selanjutnya terdaftar jasmine-matcherspertama).

expect().toBeTrue() didefinisikan sebagai:

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

Bedanya dengan expect().toBeTrue()dan expect().toBe(true)adalah bahwa expect().toBeTrue()tes apakah itu berurusan dengan Booleanobjek. expect(new Boolean(true)).toBe(true)akan gagal sedangkan expect(new Boolean(true)).toBeTrue()akan lulus. Ini karena hal lucu ini:

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

Setidaknya itu benar:

> !!new Boolean(true)
true

Mana yang paling cocok untuk digunakan elem.isDisplayed()?

Akhirnya busur derajat menyerahkan permintaan ini ke Selenium. The dokumentasi menyatakan bahwa nilai yang dihasilkan oleh .isDisplayed()sebuah janji bahwa resolve ke boolean. Saya akan mengambil nilai nominal dan menggunakan .toBeTrue()atau .toBe(true). Jika saya menemukan kasus di mana implementasinya mengembalikan nilai kebenaran / kepalsuan, saya akan mengajukan laporan bug.

Louis
sumber
20

Di javascript ada trues dan truthys. Ketika sesuatu itu benar itu jelas benar atau salah. Ketika sesuatu itu benar itu mungkin atau mungkin bukan boolean, tetapi nilai "pemeran" adalah boolean.

Contohnya.

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

Ini bisa membuat segalanya lebih sederhana jika Anda ingin memeriksa apakah string disetel atau array memiliki nilai apa pun.

var users = [];

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

var name = "";

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

Dan seperti yang dinyatakan. expect(something).toBe(true)dan expect(something).toBeTrue()sama. Tetapi expect(something).toBeTruthy()tidak sama dengan keduanya.

mikah
sumber
2
[] == false;tidak benar, pernyataan itu sendiri salah karena objek selalu benar
dandavis
@andavis Tangkapan bagus
micah
@andavis Tidak benar. Objek tidak selalu benar. Tetapi pernyataan itu [] == false;adalahtrue
mikah
2
tidak, itu tidak berguna, justru sebaliknya: itu adalah noob gotcha ... pertimbangkan [""]==falseatau [0]== false; tidak kosong, tidak falsey, hanya menipu ...
dandavis
2
Menggunakan x == trueseperti yang Anda miliki dalam contoh Anda adalah menyesatkan dan, seperti yang ditunjukkan oleh komentar di atas, cara yang salah untuk menggambarkan konsep kebenaran dalam JavaScript. Tes sebenarnya dari kebenaran dalam JavaScript adalah bagaimana nilai berperilaku dalam ifpernyataan atau sebagai operan dalam ekspresi boolean. Kami tahu 1benar karena if (1)akan menyebabkan pernyataan berikutnya dievaluasi. Demikian juga []kebenaran karena alasan yang sama: Meskipun [] == truedievaluasi false, if ([])masih akan menyebabkan pernyataan berikutnya dievaluasi, jadi kita tahu []itu benar.
Jordan Running
13

Disclamer : Ini hanya tebakan liar

Saya tahu semua orang menyukai daftar yang mudah dibaca:

  • toBe(<value>) - Nilai yang dikembalikan sama dengan <value>
  • toBeTrue() - Memeriksa apakah nilai yang dikembalikan adalah true
  • toBeTruthy() - Periksa apakah nilai, ketika dilemparkan ke boolean, akan menjadi nilai yang benar

    Nilai truthy semua nilai-nilai yang tidak 0, ''(string kosong), false, null, NaN, undefinedatau [](array kosong) *.

    * Perhatikan bahwa ketika Anda menjalankan !![], ia kembali true, tetapi ketika Anda menjalankannya [] == falsejuga kembali true. Itu tergantung pada bagaimana itu diterapkan. Dengan kata lain:(!![]) === ([] == false)


Pada contoh Anda, toBe(true)dan toBeTrue()akan menghasilkan hasil yang sama.

Ismael Miguel
sumber
Array kosong adalah falsey.
micah
@MicahWilliamson Terima kasih! Memperbaiki jawabannya
Ismael Miguel
3
array kosong adalah 100% benar di JSalert(!![])
dandavis
@andavis [] == truedi konsol Anda menghasilkan false. [] == falsedi Anda konsol menghasilkantrue
mikah
@MicahWilliamson: itu karena Anda membandingkan versi string dari array (string kosong) dengan true. itu bisa membingungkan ...
dandavis
1

Ada banyak jawaban bagus di luar sana, saya hanya ingin menambahkan skenario di mana penggunaan harapan ini mungkin bisa membantu. Menggunakan element.all(xxx), jika saya perlu memeriksa apakah semua elemen ditampilkan pada sekali jalan, saya dapat melakukan -

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

Alasannya .all()mengembalikan sebuah array nilai dan segala macam harapan ( getText, isPresent, dll ...) dapat dilakukan dengan toBeTruthy()ketika .all()datang ke dalam gambar. Semoga ini membantu.

Sortir Girish
sumber
Bagus! Saya ingat reduce()-sing array booleans menjadi nilai tunggal dan kemudian menerapkan toBe(true)cek. Ini jauh lebih sederhana, terima kasih.
alecxe