web-dev-qa-db-fra.com

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

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

Notez que toBeTrue() est un adapteur personnalisé introduit dans jasmine-matchers parmi d’autres correspondants utiles et pratiques comme toHaveMethod() ou toBeArrayOfStrings().


La question est censée être générique, mais comme exemple concret, je teste qu'un élément est affiché dans protractor. Quel matcher devrais-je utiliser dans ce cas?

_expect(Elm.isDisplayed()).toBe(true);
expect(Elm.isDisplayed()).toBeTruthy();
expect(Elm.isDisplayed()).toBeTrue();
_
127
alecxe

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

être()

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

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

Il effectue son test avec ===, ce qui signifie que, lorsqu'il est utilisé en tant que expect(foo).toBe(true), il ne passera que si foo a réellement la valeur true. Les valeurs de vérité ne feront pas passer le test.

toBeTruthy ()

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

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

Type de coercition

Une valeur est vérité 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 , == true n'est pas un test correct pour la véracité. Vous aurez des choses drôles comme

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

Considérant que l’utilisation de !! donne:

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

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

pour être vrai()

expect().toBeTrue() fait partie de Jasmine-Matchers (qui est enregistré sur npm en tant que jasmine-expect après un projet ultérieur enregistré jasmine-matchers en premier).

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

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() vérifie s'il traite ou non avec un objet Boolean. expect(new Boolean(true)).toBe(true) échouerait alors que expect(new Boolean(true)).toBeTrue() réussirait. C'est à cause de cette chose amusante:

> 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. Le documentation indique que la valeur produite par .isDisplayed() est une promesse qui se résout en un boolean. Je le prendrais au pied de la lettre et utiliserais .toBeTrue() ou .toBe(true). Si je trouvais un cas où l’implémentation renvoie des valeurs vérité/fausseté, je déposerais un rapport de bogue.

178
Louis

En javascript, il y a des vrais et des vrais. Quand quelque chose est vrai, c'est évidemment vrai ou faux. Quand quelque chose est vrai, cela peut être ou ne pas être un booléen, mais la valeur de "distribution" 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 voulez 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() est identique. Mais expect(something).toBeTruthy() n'est pas le même que l'un ou l'autre.

15
micah

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 identique à <value>
  • toBeTrue() - Vérifie si la valeur renvoyée est true
  • toBeTruthy() - Vérifier si la valeur, lorsqu'elle est convertie en un booléen, sera une valeur de vérité

    Les valeurs de vérité sont toutes les valeurs qui ne sont pas 0, '' (chaîne vide), false, null, NaN, undefined ou [] (tableau vide) *.

    * Notez que lorsque vous exécutez !![], il renvoie true, mais lorsque vous exécutez [] == false, il renvoie également true. Cela dépend de la façon dont il est mis en œuvre. En d'autres termes: (!![]) === ([] == false)


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

11
Ismael Miguel

Il y a beaucoup de bonnes réponses, je voulais simplement ajouter un scénario dans lequel l'utilisation de ces attentes pourrait être utile. En utilisant element.all(xxx), si je dois vérifier si tous les éléments sont affichés en une 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

La raison d'être .all() renvoie un tableau de valeurs et donc toutes sortes d'attentes (getText, isPresent, etc ...) peuvent être effectuées avec toBeTruthy() lorsque .all() entre en image. J'espère que cela t'aides.

1
Girish Sortur