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

165

Was ist der Unterschied zwischen expect(something).toBe(true), expect(something).toBeTruthy()und expect(something).toBeTrue()?

Beachten Sie, dass dies toBeTrue()ein benutzerdefinierter Matcher ist , der jasmine-matchersunter anderen nützlichen und praktischen Matchern wie toHaveMethod()oder eingeführt wurde toBeArrayOfStrings().


Die Frage soll allgemein gehalten sein, aber als Beispiel aus der Praxis teste ich, ob ein Element in angezeigt wird protractor. Welchen Matcher soll ich in diesem Fall verwenden?

expect(elm.isDisplayed()).toBe(true);
expect(elm.isDisplayed()).toBeTruthy();
expect(elm.isDisplayed()).toBeTrue();
Alecxe
quelle
3
Ich denke .toBe(true)== .toBeTrue(). toBeTruthy () kann nicht nur wahr sein , sondern auch 123 , "dfgdfg", [1,2,3] usw. sind im Grunde if(x==true)wahr, während if(x===true)wahr wahr sind.
Dandavis
2
Dies kann helfen
ODelibalta
2
Das hängt davon ab, welchen Wert Sie testen. Verwenden toBeTruthySie diese Option, wenn Sie sich nicht sicher sind, welcher Typ derselbe ist, == trueobwohl ich vermute, dass er .toBe(true)derselbe ist wie === trueMind you. Es ist ein wenig übertrieben, eine Funktion aufzurufen, um auf true zu testen. Ein Rat,. Vergiss ==und !=existiert in Javascript und benutze es nie wieder. Wahrheit ist nicht nötig und eine Falle für Anfänger. Verwenden Sie ===und !==stattdessen.
Blindman67
@ Blindman67 danke für den Rat, es macht vollkommen Sinn. Wir haben eslintuns sogar gemeldet, ob ==oder !=werden vorgeschlagen, dies in ===und zu ändern !==.
Alecxe

Antworten:

231

Was ich mache, wenn ich mich so etwas wie die hier gestellte Frage frage, ist, zur Quelle zu gehen.

sein()

expect().toBe() ist definiert als:

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

Es führt seinen Test durch, ===was bedeutet, dass es bei Verwendung als expect(foo).toBe(true)nur bestanden wird, wenn es footatsächlich den Wert hat true. Wahrheitswerte bestehen den Test nicht.

toBeTruthy ()

expect().toBeTruthy() ist definiert als:

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

Typ Zwang

Ein Wert ist wahr, wenn der Zwang dieses Wertes zu einem Booleschen Wert den Wert ergibt true. Die Operation !!prüft die Richtigkeit, indem der expectan einen Booleschen Wert übergebene Wert erzwungen wird . Beachten Sie, dass im Gegensatz zu dem, was die derzeit akzeptierte Antwort impliziert , == trueist nicht für Truthiness eine richtige Prüfung. Sie werden lustige Dinge wie bekommen

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

Bei Verwendung von !!Erträgen:

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

(Ja, leer oder nicht, ein Array ist wahr.)

toBeTrue ()

expect().toBeTrue()ist Teil von Jasmine-Matchers (das auf npm registriert ist, wie jasmine-expectnach einem späteren Projekt, das jasmine-matcherszuerst registriert wurde ).

expect().toBeTrue() ist definiert als:

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

Der Unterschied zu expect().toBeTrue()und expect().toBe(true)besteht darin, dass expect().toBeTrue()geprüft wird, ob es sich um ein BooleanObjekt handelt. expect(new Boolean(true)).toBe(true)würde scheitern, während expect(new Boolean(true)).toBeTrue()passieren würde. Das liegt an dieser lustigen Sache:

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

Zumindest ist es wahr:

> !!new Boolean(true)
true

Welches ist am besten für die Verwendung geeignet elem.isDisplayed()?

Letztendlich übergibt der Winkelmesser diese Anfrage an Selen. Die Dokumentation besagt, dass der von erzeugte Wert .isDisplayed()ein Versprechen ist, das sich in a auflöst boolean. Ich würde es zum Nennwert nehmen und .toBeTrue()oder verwenden .toBe(true). Wenn ich einen Fall finden würde, in dem die Implementierung Wahrheits- / Falschwerte zurückgibt, würde ich einen Fehlerbericht einreichen.

Louis
quelle
20

In Javascript gibt es Wahrheiten und Wahrheiten. Wenn etwas wahr ist, ist es offensichtlich wahr oder falsch. Wenn etwas wahr ist, kann es ein Boolescher Wert sein oder auch nicht, aber der "Cast" -Wert von ist ein Boolescher Wert.

Beispiele.

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

Dies kann die Arbeit vereinfachen, wenn Sie überprüfen möchten, ob eine Zeichenfolge festgelegt ist oder ein Array Werte enthält.

var users = [];

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

var name = "";

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

Und wie gesagt. expect(something).toBe(true)und expect(something).toBeTrue()ist das gleiche. Ist expect(something).toBeTruthy()aber nicht dasselbe wie beides.

Micah
quelle
2
[] == false;ist nicht richtig, die Aussage selbst ist falsch, weil Objekte immer wahr sind
Dandavis
@ Dandavis Guter Fang
Micah
@ Dandavis Nicht wahr. Objekte sind nicht immer wahr. Aber diese Aussage [] == false;isttrue
Micah
2
nein, es ist nicht nützlich, im Gegenteil: es ist ein Noob Gotcha ... überlegen Sie [""]==falseoder [0]== false; nicht leer, nicht falsey, nur trügerisch ...
Dandavis
2
Die Verwendung x == truewie in Ihren Beispielen ist eine irreführende und, wie die obigen Kommentare zeigen, falsche Darstellung des Konzepts der Wahrhaftigkeit in JavaScript. Der eigentliche Test der Wahrhaftigkeit in JavaScript besteht darin, wie sich ein Wert in einer ifAnweisung oder als Operand in einem booleschen Ausdruck verhält . Wir wissen, dass dies 1wahr ist, da if (1)dadurch die nächste Aussage bewertet wird. Ebenso []ist es aus dem gleichen Grund wahr: Auch wenn es sich um eine [] == trueBewertung handelt false, if ([])wird die nächste Aussage dennoch bewertet, sodass wir wissen, dass sie []wahr ist.
Jordan läuft
13

Disclamer : Dies ist nur eine wilde Vermutung

Ich weiß, dass jeder eine einfach zu lesende Liste liebt:

  • toBe(<value>) - Der zurückgegebene Wert ist der gleiche wie <value>
  • toBeTrue() - Überprüft, ob der zurückgegebene Wert ist true
  • toBeTruthy() - Überprüfen Sie, ob der Wert, wenn er in einen Booleschen Wert umgewandelt wird, ein wahrer Wert ist

    Truthy Werte sind alle Werte, die nicht 0, ''(leere Zeichenkette), false, null, NaN, undefinedoder [](Leer - Array) *.

    * Beachten Sie !![], dass beim Ausführen zurückgegeben wird true, beim Ausführen [] == falsejedoch auch true. Es hängt davon ab, wie es implementiert wird. Mit anderen Worten:(!![]) === ([] == false)


In Ihrem Beispiel toBe(true)und toBeTrue()wird die gleichen Ergebnisse liefern.

Ismael Miguel
quelle
Ein leeres Array ist Falsey.
Micah
@ MicahWilliamson Danke! Die Antwort wurde
korrigiert
3
leere Arrays sind 100% wahr in JSalert(!![])
Dandavis
@dandavis [] == truein Ihrer Konsole erzeugt false. [] == falsein Ihrer Konsole produzierttrue
Micah
@MicahWilliamson: Das liegt daran, dass Sie die String-Version des Arrays (leere String) mit true vergleichen. es kann verwirrend sein ...
Dandavis
1

Es gibt viele gute Antworten, ich wollte nur ein Szenario hinzufügen, in dem die Verwendung dieser Erwartungen hilfreich sein könnte. Mit element.all(xxx), wenn ich überprüfen muss, ob alle Elemente in einem einzigen Lauf angezeigt werden, kann ich ausführen -

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

Grund dafür .all()gibt ein Array von Werten und so alle Arten von Erwartungen ( getText, isPresent, etc ...) kann mit durchgeführt werden , toBeTruthy()wenn .all()kommt ins Bild. Hoffe das hilft.

Girish Sortur
quelle
Nett! Ich erinnere mich, wie ich reduce()das Array von Booleschen Werten in einen einzigen Wert umgewandelt und dann die toBe(true)Prüfung angewendet habe . Das ist viel einfacher, danke.
Alecxe