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


166

Qual'è la differenza tra expect(something).toBe(true), expect(something).toBeTruthy()e expect(something).toBeTrue()?

Nota che toBeTrue()è un matcher personalizzato introdotto jasmine-matcherstra gli altri matcher utili e pratici come toHaveMethod()o toBeArrayOfStrings().


La domanda è pensata per essere generica, ma, come esempio nel mondo reale, sto testando la visualizzazione di un elemento protractor. Quale matcher dovrei usare in questo caso?

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

3
penso .toBe(true)== .toBeTrue(). toBeTruthy () può essere vero non solo su vero , ma su 123 , "dfgdfg", [1,2,3], ecc ... fondamentalmente if(x==true)sono veri, mentre if(x===true)sono veri veri.
dandavis,


2
Ciò dipenderà dal valore che stai testando. Usa toBeTruthyse non sei sicuro del tipo che è lo stesso di == truementre sospetto .toBe(true)sia lo stesso di === trueMind you è un po 'fuori bordo chiamare una funzione per testare la verità. Parola di consiglio. Dimentica ==ed !=esiste in Javascript e non lo usi mai più. La verità non è necessaria e una trappola per i principianti. Usa ===e !==invece.
Blindman67,

@ Blindman67 grazie per il consiglio, ha perfettamente senso. Abbiamo anche eslintsegnalato se ==o !=vengono utilizzati suggerendo di cambiarlo in ===e !==.
Alecxe,

Risposte:


231

Quello che faccio quando mi chiedo qualcosa come la domanda posta qui è andare alla fonte.

essere()

expect().toBe() è definito come:

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

Esegue il suo test con il ===quale significa che se usato come expect(foo).toBe(true), passerà solo se fooeffettivamente ha il valore true. I valori veritieri non supereranno il test.

toBeTruthy ()

expect().toBeTruthy() è definito come:

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

Digita coercizione

Un valore è vero se la coercizione di questo valore a un valore booleano fornisce il valore true. L'operazione !!verifica la veridicità forzando il valore passato expecta un valore booleano. Si noti che contrariamente a quanto implica la risposta attualmente accettata , non== true è un test corretto per la verità. Avrai cose divertenti come

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

Considerando che usando i !!rendimenti:

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

(Sì, vuoto o no, un array è veritiero.)

per essere vero()

expect().toBeTrue()fa parte di Jasmine-Matchers (che è registrato su npm come jasmine-expectdopo un progetto successivo registrato per jasmine-matchersprimo).

expect().toBeTrue() è definito come:

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

La differenza con expect().toBeTrue()e expect().toBe(true)è che expect().toBeTrue()verifica se si tratta di un Booleanoggetto. expect(new Boolean(true)).toBe(true)fallirebbe mentre expect(new Boolean(true)).toBeTrue()passerebbe. Ciò è dovuto a questa cosa divertente:

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

Almeno è vero:

> !!new Boolean(true)
true

Quale è più adatto per l'uso con elem.isDisplayed()?

Alla fine il goniometro consegna questa richiesta al selenio. La documentazione afferma che il valore prodotto da .isDisplayed()è una promessa che si risolve in a boolean. Lo prenderei per valore nominale e uso .toBeTrue()o .toBe(true). Se trovassi un caso in cui l'implementazione restituisce valori di verità / falsità, presenterei una segnalazione di bug.


20

In javascript ci sono verità e verità. Quando qualcosa è vero, è ovviamente vero o falso. Quando qualcosa è vero, può essere o meno un valore booleano, ma il valore "cast" di è un valore booleano.

Esempi.

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

Ciò può semplificare le cose se si desidera verificare se è impostata una stringa o se un array ha valori.

var users = [];

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

var name = "";

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

E come detto. expect(something).toBe(true)ed expect(something).toBeTrue()è lo stesso. Ma expect(something).toBeTruthy()non è uguale a nessuno dei due.


2
[] == false;non è corretto, l'affermazione stessa è falsa perché gli oggetti sono sempre veritieri
dandavis,

@dandavis Buona cattura
Micah

@dandavis Non è vero. Gli oggetti non sono sempre veri. Ma questa affermazione [] == false;ètrue
Michea,

2
no, non è utile, anzi il contrario: è un noob gotcha ... considera [""]==falseo [0]== false; non vuoto, non falso, solo ingannevole ...
dandavis,

2
Usare x == truecome hai nei tuoi esempi è un modo fuorviante e, come mostrano i commenti sopra, modo errato di illustrare il concetto di verità in JavaScript. Il vero test di verità in JavaScript è come si comporta un valore in ifun'istruzione o come operando in un'espressione booleana. Sappiamo che 1è vero perché if (1)causerà la valutazione della prossima affermazione. Allo stesso modo []è vero per lo stesso motivo: anche se [] == truevaluta false, if ([])farà comunque valutare la prossima affermazione, quindi sappiamo che []è vero.
Jordan, in esecuzione il

13

Disclamer : questa è solo un'ipotesi selvaggia

So che a tutti piace un elenco di facile lettura:

  • toBe(<value>) - Il valore restituito è uguale a <value>
  • toBeTrue() - Verifica se il valore restituito è true
  • toBeTruthy() - Controlla se il valore, se lanciato su un valore booleano, sarà un valore veritiero

    Valori Truthy sono tutti valori che non sono 0, ''(stringa vuota), false, null, NaN, undefinedo [](array vuoto) *.

    * Notare che quando si esegue !![], ritorna true, ma quando si esegue [] == falserestituisce anche true. Dipende da come viene implementato. In altre parole:(!![]) === ([] == false)


Nel tuo esempio, toBe(true)e toBeTrue()otterrai gli stessi risultati.


Un array vuoto è falso.
Michea,

@MicahWilliamson Grazie! Risolto il problema con la risposta
Ismael Miguel,

3
gli array vuoti sono veritieri al 100% in JSalert(!![])
dandavis il

@dandavis [] == truenella tua console produce false. [] == falsein you console producetrue
micah,

@MicahWilliamson: questo perché stai confrontando la versione di stringa dell'array (stringa vuota) con true. può essere
fonte di

1

Ci sono molte buone risposte là fuori, volevo solo aggiungere uno scenario in cui l'uso di queste aspettative potrebbe essere utile. Utilizzando element.all(xxx), se devo verificare se tutti gli elementi sono visualizzati in una sola corsa, posso eseguire -

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

Ragione di essere .all()restituisce una matrice di valori e così tutti i tipi di aspettative ( getText, isPresent, ecc ...) può essere effettuata con toBeTruthy()cui .all()entra in foto. Spero che questo ti aiuti.


Bello! Ricordo di aver reduce()inserito l'array di booleani in un unico valore e quindi di applicare il toBe(true)controllo. Questo è molto più semplice, grazie.
Alecxe
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.