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

165

Jaka jest różnica między expect(something).toBe(true), expect(something).toBeTruthy()i expect(something).toBeTrue()?

Zauważ, że toBeTrue()jest to niestandardowy element dopasowujący wprowadzony jasmine-matcherswśród innych przydatnych i przydatnych dopasowań, takich jak toHaveMethod()lub toBeArrayOfStrings().


Pytanie ma być ogólne, ale jako przykład ze świata rzeczywistego testuję, czy element jest wyświetlany protractor. Którego dopasowania powinienem użyć w tym przypadku?

expect(elm.isDisplayed()).toBe(true);
expect(elm.isDisplayed()).toBeTruthy();
expect(elm.isDisplayed()).toBeTrue();
alecxe
źródło
3
myślę .toBe(true)== .toBeTrue(). toBeTruthy () może być prawdziwe nie tylko na podstawie true , ale także na 123 , "dfgdfg", [1, 2, 3], itd ... w zasadzie if(x==true)są prawdziwe, podczas gdy if(x===true)są prawdziwe.
dandavis
2
To może pomóc
ODelibalta
2
Będzie to zależeć od wartości, którą testujesz. Użyj, toBeTruthyjeśli nie jesteś pewien typu, jest on taki sam, jak == truepodczas gdy podejrzewam, że .toBe(true)jest taki sam, jak === truePamiętaj, że to trochę za burtą, aby wywołać funkcję, aby sprawdzić, czy jest prawda. Słowo porady. Zapomnij ==i !=istnieje w Javascript i nigdy nie używaj go ponownie. Prawda nie jest potrzebna i jest pułapką dla początkujących. Użyj ===i !==zamiast tego.
Blindman67
@ Blindman67 dzięki za radę, to ma sens. Mamy nawet eslintzgłoszenie do nas, jeśli ==lub !=są wykorzystywane sugeruje, aby zmienić ===i !==.
alecxe

Odpowiedzi:

231

To, co robię, gdy zastanawiam się, jak zadane tutaj pytanie, to skierowanie się do źródła.

być()

expect().toBe() definiuje się jako:

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

Wykonuje swój test, ===co oznacza, że ​​gdy jest używany jako expect(foo).toBe(true), przejdzie tylko wtedy, gdy foofaktycznie ma wartość true. Prawdziwe wartości nie przejdą testu.

toBeTruthy ()

expect().toBeTruthy() definiuje się jako:

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

Wymuszenie typu

Wartość jest prawdziwa, jeśli wymuszenie tej wartości na wartość logiczną daje wartość true. Operacja !!sprawdza prawdziwość przez wymuszenie wartości przekazanej do wartości expectlogicznej. Zauważ, że wbrew temu, co sugeruje obecnie przyjęta odpowiedź , nie== true jest to poprawny test na prawdziwość. Dostaniesz zabawne rzeczy, takie jak

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

Natomiast używając !!plonów:

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

(Tak, pusta czy nie, tablica jest prawdziwa).

szczerze mówiąc()

expect().toBeTrue()jest częścią Jasmine-Matchers (który jest zarejestrowany na npm jak jasmine-expectpóźniejszy projekt zarejestrowany jako jasmine-matcherspierwszy).

expect().toBeTrue() definiuje się jako:

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

Różnica między expect().toBeTrue()i expect().toBe(true)polega na tym, że expect().toBeTrue()testuje, czy ma do czynienia z Booleanobiektem. expect(new Boolean(true)).toBe(true)zawiedzie, podczas gdy expect(new Boolean(true)).toBeTrue()przejdzie. To z powodu tej zabawnej rzeczy:

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

Przynajmniej jest to prawda:

> !!new Boolean(true)
true

Który najlepiej nadaje się do użytku z elem.isDisplayed()?

Ostatecznie Protractor przekazuje tę prośbę Selenium. Dokumentacja wskazuje, że wartość wytworzona przez .isDisplayed()to obietnica, że rozpoznawany jako boolean. Wziąłbym to za wartość nominalną i użyłbym .toBeTrue()lub .toBe(true). Gdybym znalazł przypadek, w którym implementacja zwraca prawdziwe / fałszywe wartości, zgłosiłbym błąd.

Louis
źródło
20

W javascript są prawda i prawda. Kiedy coś jest prawdą, jest to oczywiście prawda lub fałsz. Kiedy coś jest prawdziwe, może to być wartość logiczna lub nie, ale wartość „rzutowania” jest wartością logiczną.

Przykłady.

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

Może to uprościć sprawę, jeśli chcesz sprawdzić, czy ciąg jest ustawiony lub czy tablica ma jakieś wartości.

var users = [];

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

var name = "";

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

I jak stwierdzono. expect(something).toBe(true)i expect(something).toBeTrue()jest taki sam. Ale expect(something).toBeTruthy()to nie to samo, co którekolwiek z nich.

micah
źródło
2
[] == false;nie jest poprawne, samo stwierdzenie jest fałszywe, ponieważ przedmioty są zawsze zgodne z prawdą
dandavis
@dandavis Dobry chwyt
micah
@dandavis Nie prawda. Przedmioty nie zawsze są prawdziwe. Ale to stwierdzenie [] == false;brzmitrue
micah
2
nie, to nie jest przydatne, wręcz przeciwnie: to jest noob gotcha… rozważ [""]==falselub [0]== false; nie pusty, nie falsey, po prostu zwodniczy ...
dandavis
2
Używanie tego, x == trueco masz w swoich przykładach, jest mylącym i, jak pokazują powyższe komentarze, niewłaściwym sposobem zilustrowania pojęcia prawdziwości w JavaScript. Prawdziwym testem prawdziwości w JavaScript jest to, jak wartość zachowuje się w ifinstrukcji lub jako operand w wyrażeniu boolowskim. Wiemy, że 1jest prawdą, ponieważ if (1)spowoduje, że następne stwierdzenie zostanie ocenione. Podobnie []jest z prawdą z tego samego powodu: mimo że szacuje się [] == truedo false, if ([])nadal spowoduje, że następne zdanie zostanie ocenione, więc wiemy, że []jest prawdziwe.
Jordan Bieganie,
13

Disclamer : To tylko szalone przypuszczenie

Wiem, że wszyscy uwielbiają łatwą do odczytania listę:

  • toBe(<value>) - Zwrócona wartość jest taka sama jak <value>
  • toBeTrue() - Sprawdza, czy zwrócona wartość to true
  • toBeTruthy() - Sprawdź, czy wartość rzutowana na wartość logiczną będzie zgodna z prawdą

    Wartości Truthy są wszystkie wartości, które nie są 0, ''(pusty ciąg znaków), false, null, NaN, undefinedlub [](pusty tablicy) *.

    * Zwróć uwagę, że po uruchomieniu !![]zwraca true, ale po uruchomieniu [] == falserównież powraca true. To zależy od tego, jak zostanie wdrożone. Innymi słowy:(!![]) === ([] == false)


Na twoim przykładzie toBe(true)i toBeTrue()przyniesie te same wyniki.

Ismael Miguel
źródło
Pusta tablica to błąd.
micah
@MicahWilliamson Thanks! Naprawiono odpowiedź
Ismael Miguel
3
puste tablice są w 100% prawdziwe w JSalert(!![])
dandavis
@dandavis [] == truew twojej konsoli produkuje false. [] == falsew twojej konsoli produkujetrue
micah
@MicahWilliamson: to dlatego, że porównujesz ciągową wersję tablicy (pusty ciąg) z wartością true. to może być mylące ...
dandavis
1

Istnieje wiele dobrych odpowiedzi, chciałem tylko dodać scenariusz, w którym wykorzystanie tych oczekiwań może być pomocne. Używając element.all(xxx), jeśli muszę sprawdzić, czy wszystkie elementy są wyświetlane w jednym przebiegu, mogę wykonać -

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

Powodem jest .all()zwraca tablicę wartości, a więc wszelkiego rodzaju oczekiwań ( getText, isPresentitd ...) mogą być wykonywane toBeTruthy(), gdy .all()wchodzi w obraz. Mam nadzieję że to pomoże.

Girish Sortur
źródło
Miły! Pamiętam, że reduce()zapisałem tablicę wartości logicznych w jednej wartości, a następnie zastosowałem toBe(true)sprawdzenie. Dziękuję, to jest o wiele prostsze.
alecxe