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

166

Quelle est la différence entre expect(something).toBe(true), expect(something).toBeTruthy()et expect(something).toBeTrue()?

Notez que toBeTrue() s'agit d'un matcher personnalisé introduit jasmine-matchersparmi d'autres matchers utiles et pratiques comme toHaveMethod()ou toBeArrayOfStrings().


La question est censée être générique, mais, à titre d'exemple réel, je teste qu'un élément est affiché dans protractor. Quel matcher dois-je utiliser dans ce cas?

expect(elm.isDisplayed()).toBe(true);
expect(elm.isDisplayed()).toBeTruthy();
expect(elm.isDisplayed()).toBeTrue();
alecxe
la source
3
je pense .toBe(true)== .toBeTrue(). toBeTruthy () peut être vrai non seulement sur vrai , mais sur 123 , "dfgdfg", [1, 2, 3], etc ... if(x==true)sont fondamentalement véridiques, alors que if(x===true)sont vrais vrais.
dandavis
2
Cela peut aider
ODelibalta
2
Cela dépendra de la valeur que vous testez. À utiliser toBeTruthysi vous n'êtes pas sûr du type, c'est le même que, == truealors que je soupçonne que .toBe(true)c'est le même que === trueMind you, c'est un peu exagéré d'appeler une fonction à tester pour vrai. Un conseil ,. Oubliez ==et !=existe en Javascript et ne l'utilisez plus jamais. La vérité n'est pas nécessaire et un piège pour les débutants. Utilisez ===et à la !==place.
Blindman67
@ Blindman67 merci pour les conseils, il est parfaitement logique. Nous avons même eslintsignalé si ==ou !=sont utilisés suggérant de le changer en ===et !==.
alecxe du

Réponses:

231

Ce que je fais quand je me demande quelque chose comme la question posée ici, c'est d'aller à la source.

être()

expect().toBe() est défini comme:

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

Il effectue son test avec ===ce qui signifie que lorsqu'il est utilisé comme expect(foo).toBe(true), il ne passera que s'il a fooréellement la valeur true. Des valeurs véridiques ne feront pas passer le test.

toBeTruthy ()

expect().toBeTruthy() est défini comme:

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

Coercition de type

Une valeur est vraie si la contrainte de cette valeur sur un booléen donne la valeur true. L'opération !!teste la véracité en contraignant la valeur transmise expectà un booléen. Notez que contrairement à ce que la réponse actuellement acceptée implique , == truen'est pas un test correct pour la véracité. Vous aurez des choses amusantes comme

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

Alors qu'en utilisant les !!rendements:

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

(Oui, vide ou non, un tableau est la vérité.)

pour être vrai()

expect().toBeTrue()fait partie de Jasmine-Matchers (qui est enregistré sur npm comme jasmine-expectaprès un projet ultérieur enregistré en jasmine-matcherspremier).

expect().toBeTrue() est défini comme:

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

La différence avec expect().toBeTrue()et expect().toBe(true)est que expect().toBeTrue()teste s'il s'agit d'un Booleanobjet. expect(new Boolean(true)).toBe(true)échouerait alors expect(new Boolean(true)).toBeTrue()que passerait. C'est à cause de cette drôle de chose:

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

Au moins c'est la vérité:

> !!new Boolean(true)
true

Quel est le mieux adapté pour une utilisation avec elem.isDisplayed() ?

En fin de compte, Protractor transmet cette demande à Selenium. La documentation indique que la valeur produite par .isDisplayed()est une promesse qui se résout en a boolean. Je le prendrais au pied de la lettre et utiliserais .toBeTrue()ou .toBe(true). Si je trouve un cas où l'implémentation renvoie des valeurs véridiques / fausses, je déposerais un rapport de bogue.

Louis
la source
20

En javascript, il y a des vérités et des vérités. Quand quelque chose est vrai, c'est évidemment vrai ou faux. Quand quelque chose est véridique, il peut ou non être un booléen, mais la valeur «cast» de est un booléen.

Exemples.

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

Cela peut simplifier les choses si vous souhaitez vérifier si une chaîne est définie ou si un tableau a des valeurs.

var users = [];

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

var name = "";

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

Et comme indiqué. expect(something).toBe(true)et expect(something).toBeTrue()c'est pareil. Mais ce expect(something).toBeTruthy()n'est pas la même chose que l'un ou l'autre.

micah
la source
2
[] == false;n'est pas correcte, la déclaration elle-même est fausse car les objets sont toujours véridiques
dandavis
@dandavis Good catch
micah
@dandavis Pas vrai. Les objets ne sont pas toujours véridiques. Mais cette déclaration [] == false;esttrue
micah
2
non, ce n'est pas utile, juste le contraire en fait: c'est un noob gotcha ... considérez [""]==falseou [0]== false; pas vide, pas faux, juste trompeur ...
dandavis
2
Utiliser ce x == trueque vous avez dans vos exemples est une manière trompeuse et, comme le montrent les commentaires ci-dessus, incorrecte d'illustrer le concept de véracité en JavaScript. Le véritable test de véracité en JavaScript est de savoir comment une valeur se comporte dans une ifinstruction ou en tant qu'opérande dans une expression booléenne. Nous savons que 1c'est la vérité parce que if (1)cela entraînera l'évaluation de la prochaine déclaration. Il en va de même []pour la vérité pour la même raison: même si elle [] == trueévalue false, if ([])entraînera toujours l' évaluation de la prochaine déclaration, donc nous savons que []c'est la vérité.
Jordan Running du
13

Disclamer : Ceci est juste une supposition sauvage

Je sais que tout le monde aime une liste facile à lire:

  • toBe(<value>) - La valeur renvoyée est la même que <value>
  • toBeTrue() - Vérifie si la valeur renvoyée est true
  • toBeTruthy() - Vérifiez si la valeur, lorsqu'elle est convertie en booléen, sera une valeur de vérité

    Les valeurs Truthy sont toutes les valeurs qui ne sont pas 0, ''(chaîne vide), false, null, NaN, undefinedou [](tableau vide) *.

    * Notez que lorsque vous exécutez !![], il revient true, mais lorsque vous exécutez, [] == falseil retourne également true. Cela dépend de la manière dont il est mis en œuvre. En d'autres termes:(!![]) === ([] == false)


Sur votre exemple, toBe(true)et toBeTrue()donnera les mêmes résultats.

Ismael Miguel
la source
Un tableau vide est faux.
micah
@MicahWilliamson Merci! Correction de la réponse
Ismael Miguel
3
les tableaux vides sont 100% véridiques dans JSalert(!![])
dandavis
@dandavis [] == truedans votre console produit false. [] == falsedans votre console produittrue
micah
@MicahWilliamson: c'est parce que vous comparez la version chaîne du tableau (chaîne vide) à true. ça peut être déroutant ...
dandavis
1

Il y a beaucoup de bonnes réponses là-bas, je voulais juste ajouter un scénario où l'utilisation de ces attentes pourrait être utile. En utilisant element.all(xxx), si j'ai besoin de vérifier si tous les éléments sont affichés en une seule fois, je peux effectuer -

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

Raison d' être .all()retourne un tableau de valeurs et donc toutes sortes d'attentes ( getText, isPresent, etc ...) peut être réalisée avec toBeTruthy()quand .all()vient en image. J'espère que cela t'aides.

Girish Sortur
la source
Agréable! Je me souviens reduce()-en du tableau de booléens en une seule valeur puis en appliquant la toBe(true)vérification. C'est beaucoup plus simple, merci.
alecxe le