toBe (đúng) so với toBeTruthy () so với toBeTrue ()


165

Sự khác biệt giữa expect(something).toBe(true), expect(something).toBeTruthy()và là expect(something).toBeTrue()gì?

Lưu ý rằng đó toBeTrue()là một công cụ đối sánh tùy chỉnh được giới thiệu trong jasmine-matcherssố các công cụ đối sánh hữu ích và tiện dụng khác như toHaveMethod()hoặc toBeArrayOfStrings().


Câu hỏi có nghĩa là chung chung, nhưng, như một ví dụ trong thế giới thực, tôi đang kiểm tra xem một yếu tố được hiển thị protractor. Tôi nên sử dụng que diêm nào trong trường hợp này?

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

3
tôi nghĩ .toBe(true)== .toBeTrue(). toBeTruthy () có thể đúng không chỉ đúng mà còn trên 123 , "dfgdfg", [1,2,3], v.v ... về cơ bản if(x==true)là đúng, trong khi đó if(x===true)là sự thật.
dandavis


2
Điều đó sẽ phụ thuộc vào giá trị bạn đang kiểm tra là gì. Sử dụng toBeTruthynếu bạn không chắc chắn về loại này giống như == truetrong khi tôi nghi ngờ .toBe(true)là giống như === truebạn nhớ nó hơi quá mức để gọi một chức năng để kiểm tra sự thật. Lời khuyên,. Quên ==!=tồn tại trong Javascript và không bao giờ sử dụng nó một lần nữa. Sự thật là không cần thiết và một cái bẫy cho người mới bắt đầu. Sử dụng ===!==thay vào đó.
Blindman67

@ Blindman67 cảm ơn vì lời khuyên, nó có ý nghĩa hoàn hảo. Chúng tôi thậm chí đã eslintbáo cáo cho chúng tôi nếu ==hoặc !=được sử dụng đề xuất thay đổi nó thành ===!==.
alecxe

Câu trả lời:


231

Những gì tôi làm khi tôi tự hỏi một cái gì đó giống như câu hỏi được hỏi ở đây là đi đến nguồn.

được()

expect().toBe() được định nghĩa là:

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

Nó thực hiện thử nghiệm của mình với ===nghĩa là khi được sử dụng expect(foo).toBe(true), nó sẽ chỉ vượt qua nếu foothực sự có giá trị true. Giá trị trung thực sẽ không làm cho bài kiểm tra vượt qua.

toBeTruthy ()

expect().toBeTruthy() được định nghĩa là:

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

Loại cưỡng chế

Một giá trị là trung thực nếu sự ép buộc của giá trị này đối với boolean mang lại giá trị true. Các hoạt động !!kiểm tra tính trung thực bằng cách ép buộc giá trị được chuyển expectđến một boolean. Lưu ý rằng trái với những gì các câu trả lời chấp nhận hiện nay ngụ ý , == truekhông một thử nghiệm chính xác cho truthiness. Bạn sẽ nhận được những điều hài hước như

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

Trong khi sử dụng !!sản lượng:

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

(Có, trống hay không, một mảng là trung thực.)

toBeTrue ()

expect().toBeTrue()là một phần của Jasmine-Matchers (được đăng ký vào npm như jasmine-expectsau khi dự án sau được đăng ký jasmine-matcherstrước).

expect().toBeTrue() được định nghĩa là:

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

Sự khác biệt với expect().toBeTrue()expect().toBe(true)expect().toBeTrue()kiểm tra xem nó có đang xử lý một Booleanđối tượng hay không. expect(new Boolean(true)).toBe(true)sẽ thất bại trong khi expect(new Boolean(true)).toBeTrue()sẽ vượt qua. Điều này là do điều buồn cười này:

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

Ít nhất đó là sự thật:

> !!new Boolean(true)
true

Cái nào phù hợp nhất để sử dụng với elem.isDisplayed()?

Cuối cùng Protractor đưa ra yêu cầu này cho Selenium. Các tài liệu nói rằng giá trị được tạo ra .isDisplayed()là một lời hứa giải quyết cho a boolean. Tôi sẽ lấy nó theo mệnh giá và sử dụng .toBeTrue()hoặc .toBe(true). Nếu tôi tìm thấy một trường hợp trong đó việc triển khai trả về các giá trị trung thực / giả, tôi sẽ nộp báo cáo lỗi.


20

Trong javascript có dấu vết và sự thật. Khi một cái gì đó là đúng nó rõ ràng là đúng hoặc sai. Khi một cái gì đó là sự thật, nó có thể hoặc không phải là một boolean, nhưng giá trị "cast" của là một boolean.

Ví dụ.

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

Điều này có thể làm cho mọi thứ đơn giản hơn nếu bạn muốn kiểm tra xem một chuỗi được đặt hay một mảng có bất kỳ giá trị nào không.

var users = [];

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

var name = "";

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

Và như đã nêu. expect(something).toBe(true)expect(something).toBeTrue()là như nhau. Nhưng expect(something).toBeTruthy()không giống như một trong hai.


2
[] == false;là không đúng, báo cáo kết quả bản thân là sai vì các đối tượng luôn truthy
dandavis

@dandavis Bắt tốt
micah

@dandavis Không đúng. Đối tượng không phải lúc nào cũng trung thực. Nhưng tuyên bố đó [] == false;true
micah

2
không, nó không hữu ích, thực tế thì ngược lại: đó là một gotcha noob ... xem xét [""]==falsehoặc [0]== false; không trống rỗng, không falsey, chỉ lừa đảo ...
dandavis

2
Sử dụng x == truenhư bạn có trong các ví dụ của bạn là một cách hiểu sai và, như các ý kiến ​​trên cho thấy, cách không chính xác để minh họa khái niệm về tính trung thực trong JavaScript. Thử nghiệm thực sự về tính trung thực trong JavaScript là cách một giá trị hành xử trong một ifcâu lệnh hoặc như một toán hạng trong biểu thức boolean. Chúng tôi biết 1là sự thật vì if (1)sẽ khiến cho tuyên bố tiếp theo được đánh giá. Tương tự như vậy []là sự thật vì cùng một lý do: Mặc dù được [] == trueđánh giá false, if ([])nhưng vẫn sẽ khiến cho tuyên bố tiếp theo được đánh giá, vì vậy chúng tôi biết []là sự thật.
Jordan Chạy

13

Disclamer : Đây chỉ là một phỏng đoán hoang dã

Tôi biết mọi người đều thích một danh sách dễ đọc:

  • toBe(<value>) - Giá trị trả về giống như <value>
  • toBeTrue() - Kiểm tra nếu giá trị trả về là true
  • toBeTruthy() - Kiểm tra xem giá trị, khi được chuyển thành boolean, sẽ là giá trị trung thực

    Giá trị Truthy đều giá trị mà không phải là 0, ''(trống string), false, null, NaN, undefinedhoặc [](trống mảng) *.

    * Lưu ý rằng khi bạn chạy !![], nó sẽ trả về true, nhưng khi bạn chạy [] == falsethì nó cũng trả về true. Nó phụ thuộc vào cách nó được thực hiện. Nói cách khác:(!![]) === ([] == false)


Trên ví dụ của bạn, toBe(true)toBeTrue()sẽ mang lại kết quả tương tự.


Một mảng trống là falsey.
micah

@MicahWilliamson Cảm ơn! Đã sửa câu trả lời
Ismael Miguel

3
mảng trống là 100% truthy trong JSalert(!![])
dandavis

@dandavis [] == truetrong giao diện điều khiển của bạn sản xuất false. [] == falsetrong bảng điều khiển của bạn sản xuấttrue
micah

@MicahWilliamson: đó là vì bạn đang so sánh phiên bản chuỗi của mảng (chuỗi trống) với true. nó có thể gây nhầm lẫn ...
dandavis

1

Có rất nhiều câu trả lời hay, tôi chỉ muốn thêm một kịch bản trong đó việc sử dụng những kỳ vọng này có thể hữu ích. Sử dụng element.all(xxx), nếu tôi cần kiểm tra xem tất cả các yếu tố được hiển thị trong một lần chạy, tôi có thể thực hiện -

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

Lý do là .all()trả về một mảng các giá trị và vì vậy tất cả các loại sự mong đợi ( getText, isPresent, vv ...) có thể được thực hiện với toBeTruthy()khi .all()đi vào hình ảnh. Hi vọng điêu nay co ich.


Đẹp! Tôi nhớ reduce()-ing mảng booleans thành một giá trị duy nhất và sau đó áp dụng toBe(true)kiểm tra. Điều này đơn giản hơn nhiều, cảm ơn bạn.
alecxe
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.