toBe (verdadero) vs toBeTruthy () vs toBeTrue ()

165

¿Cuál es la diferencia entre expect(something).toBe(true), expect(something).toBeTruthy()yexpect(something).toBeTrue() ?

Tenga en cuenta que toBeTrue()es un comparador personalizado introducido jasmine-matchersentre otros comparadores útiles y útiles como toHaveMethod()o toBeArrayOfStrings().


La pregunta debe ser genérica, pero, como ejemplo del mundo real, estoy probando que se muestre un elemento protractor. ¿Qué partido debo usar en este caso?

expect(elm.isDisplayed()).toBe(true);
expect(elm.isDisplayed()).toBeTruthy();
expect(elm.isDisplayed()).toBeTrue();
alecxe
fuente
3
yo pienso .toBe(true)== .toBeTrue(). toBeTruthy () puede ser verdadero no solo sobre verdadero , sino también sobre 123 , "dfgdfg", [1,2,3], etc ... básicamente if(x==true)son verdaderos, mientras que if(x===true)son verdaderos verdaderos.
dandavis
2
Esto puede ayudar
ODelibalta
2
Eso dependerá de cuál sea el valor que está probando. Úselo toBeTruthysi no está seguro del tipo, es el mismo que == truemientras sospecho que .toBe(true)es lo mismo que === trueMind you it is a little overboard to call a function to test for true. Palabra de consejo. Olvídate ==y !=existe en Javascript y nunca más lo uses. La verdad no es necesaria y una trampa para principiantes. Uso ===y en su !==lugar.
Blindman67
@ Blindman67 gracias por el consejo, tiene mucho sentido. Incluso nos han eslintinformado si se usan ==o !=se sugieren sugerir cambiarlo a ===y !==.
alecxe

Respuestas:

231

Lo que hago cuando me pregunto algo como la pregunta que se hace aquí es ir a la fuente.

ser - estar()

expect().toBe() Se define como:

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

Realiza su prueba con lo ===que significa que cuando se usa comoexpect(foo).toBe(true) , solo pasará si foorealmente tiene el valortrue . Los valores de verdad no harán pasar la prueba.

toBeTruthy ()

expect().toBeTruthy() Se define como:

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

Tipo coerción

Un valor es verdadero si la coerción de este valor a un valor booleano produce el valor true. La operación !!prueba la veracidad coaccionando el valor pasado expecta un valor booleano. Tenga en cuenta que, al contrario de lo que implica la respuesta actualmente aceptada , no== true es una prueba correcta de veracidad. Obtendrás cosas divertidas como

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

Mientras que usando !!rendimientos:

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

(Sí, vacío o no, una matriz es verdadera).

a decir verdad()

expect().toBeTrue()es parte de Jasmine-Matchers (que se registra en npm como jasmine-expectdespués de que un proyecto posterior se registrara jasmine-matchersprimero).

expect().toBeTrue() Se define como:

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

La diferencia con expect().toBeTrue()y expect().toBe(true)es que expect().toBeTrue()prueba si se trata de un Booleanobjeto. expect(new Boolean(true)).toBe(true)fallaría mientras expect(new Boolean(true)).toBeTrue()que pasaría. Esto se debe a esta cosa divertida:

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

Al menos es verdad:

> !!new Boolean(true)
true

¿Cuál es el más adecuado para usar elem.isDisplayed()?

Finalmente, el transportador le pasa esta solicitud a Selenium. La documentación establece que el valor producido por .isDisplayed()es una promesa que se resuelve en a boolean. Lo tomaría al pie de la letra y usaría .toBeTrue()o .toBe(true). Si encontré un caso donde la implementación devuelve valores de verdad / falsedad, presentaría un informe de error.

Louis
fuente
20

En javascript hay verdaderas y verdaderas. Cuando algo es cierto, obviamente es verdadero o falso. Cuando algo es verdadero, puede o no ser un booleano, pero el valor de "conversión" de es un booleano.

Ejemplos.

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

Esto puede simplificar las cosas si desea verificar si una cadena está configurada o si una matriz tiene algún valor.

var users = [];

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

var name = "";

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

Y como se dijo. expect(something).toBe(true)Y expect(something).toBeTrue()es lo mismo. Pero expect(something).toBeTruthy()no es lo mismo que ninguno de esos.

micah
fuente
2
[] == false;no es correcto, la afirmación en sí misma es falsa porque los objetos siempre son verdaderos
dandavis
@dandavis Buena captura
micah
@dandavis No es cierto. Los objetos no siempre son verdaderos. Pero esa declaración [] == false;estrue
micah
2
no, no es útil, todo lo contrario de hecho: es un novato ... considera [""]==falseo [0]== false; no vacío, no falsey, simplemente engañoso ...
dandavis
2
Usar x == truelo que tiene en sus ejemplos es una forma engañosa y, como muestran los comentarios anteriores, una forma incorrecta de ilustrar el concepto de veracidad en JavaScript. La verdadera prueba de veracidad en JavaScript es cómo se comporta un valor en una ifdeclaración o como un operando en una expresión booleana. Sabemos que 1es verdadero porque if (1)hará que se evalúe la siguiente declaración. Del mismo modo []es verdad por la misma razón: aunque[] == true evalúe como false, if ([])seguirá causando que se evalúe la siguiente declaración, por lo que sabemos que []es verdadero.
Jordan Running
13

Descargo de responsabilidad : esto es solo una suposición salvaje

Sé que a todos les encanta una lista fácil de leer:

  • toBe(<value>) - El valor devuelto es el mismo que <value>
  • toBeTrue() - Comprueba si el valor devuelto es true
  • toBeTruthy() - Compruebe si el valor, cuando se convierte en un valor booleano, será un valor verdadero

    Truthy valores son todos los valores que no son 0, ''(cadena vacía), false, null, NaN, undefinedo[] (matriz vacía) *.

    * Observe que cuando ejecuta !![], regresa true, pero cuando ejecuta [] == falsetambién regresa true. Depende de cómo se implemente. En otras palabras:(!![]) === ([] == false)


En su ejemplo, toBe(true)y toBeTrue()dará los mismos resultados.

Ismael Miguel
fuente
Una matriz vacía es falsey.
micah
@MicahWilliamson ¡Gracias! Se arregló la respuesta
Ismael Miguel
3
las matrices vacías son 100% verdaderas en JSalert(!![])
dandavis
@dandavis [] == trueen tu consola produce false. [] == falseen tu consola producetrue
micah
@MicahWilliamson: eso es porque estás comparando la versión de cadena de la matriz (cadena vacía) con verdadera. puede ser confuso ...
dandavis
1

Hay muchas buenas respuestas por ahí, solo quería agregar un escenario donde el uso de estas expectativas podría ser útil. Utilizando element.all(xxx), si necesito verificar si todos los elementos se muestran en una sola ejecución, puedo realizar:

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 razón de ser .all()devuelve una matriz de valores y así todo tipo de expectativas ( getText, isPresent, etc ...) se puede realizar con toBeTruthy()cuando se .all()entra en el cuadro. Espero que esto ayude.

Sortur Girish
fuente
¡Agradable! Recuerdo que hice una reduce()matriz de booleanos en un solo valor y luego apliqué el toBe(true)cheque. Esto es mucho más simple, gracias.
alecxe