Pruebas de JavaScript de Jasmine: toBe vs toEqual
Digamos que tengo lo siguiente:
var myNumber = 5;
expect(myNumber).toBe(5);
expect(myNumber).toEqual(5);
Ambas pruebas anteriores pasarán. ¿ Existe alguna diferencia entre toBe()
y toEqual()
cuando se trata de evaluar números? Si es así, ¿cuándo debo usar uno y no el otro?
Para tipos primitivos (por ejemplo, números, booleanos, cadenas, etc.), no hay diferencia entre toBe
y toEqual
; cualquiera de los dos funcionará para 5
, true
o "the cake is a lie"
.
Para entender la diferencia entre toBe
y toEqual
, imaginemos tres objetos.
var a = { bar: 'baz' },
b = { foo: a },
c = { foo: a };
Usando una comparación estricta ( ===
), algunas cosas son "iguales":
> b.foo.bar === c.foo.bar
true
> b.foo.bar === a.bar
true
> c.foo === b.foo
true
Pero algunas cosas, aunque sean "iguales", no son "iguales", ya que representan objetos que viven en diferentes lugares de la memoria.
> b === c
false
El comparador de Jasmine toBe
no es más que un envoltorio para una comparación de igualdad estricta.
expect(c.foo).toBe(b.foo)
es lo mismo que
expect(c.foo === b.foo).toBe(true)
No confíe sólo en mi palabra; consulte el código fuente de toBe .
Pero b
y c
representan objetos funcionalmente equivalentes; ambos se parecen
{ foo: { bar: 'baz' } }
¿No sería fantástico si pudiéramos decir eso b
y c
ser "iguales" incluso si no representan el mismo objeto?
Ingrese toEqual
, que verifica la "igualdad profunda" (es decir, realiza una búsqueda recursiva a través de los objetos para determinar si los valores de sus claves son equivalentes). Se pasarán las dos pruebas siguientes:
expect(b).not.toBe(c);
expect(b).toEqual(c);
toBe()
versus toEqual()
: toEqual()
comprueba la equivalencia. toBe()
, por otro lado, se asegura de que sean exactamente el mismo objeto.
Yo diría que se use toBe()
al comparar valores y toEqual()
al comparar objetos.
Al comparar tipos primitivos, toEqual()
se toBe()
obtendrá el mismo resultado. Al comparar objetos, toBe()
es una comparación más estricta, y si no es exactamente el mismo objeto en la memoria, devolverá falso. Entonces, a menos que quieras asegurarte de que sea exactamente el mismo objeto en la memoria, úsalo toEqual()
para comparar objetos.
Consulte este enlace para obtener más información: http://evanhahn.com/how-do-i-jasmine/
Ahora bien, al observar la diferencia entre toBe()
y toEqual()
cuando se trata de números, no debería haber ninguna diferencia siempre que la comparación sea correcta. 5
siempre será equivalente a 5
.
Un buen lugar para jugar con esto y ver diferentes resultados es aquí.
Actualizar
Una manera fácil de ver toBe()
y toEqual()
comprender qué hacen exactamente en JavaScript. Según Jasmine API, que se encuentra aquí :
toEqual() funciona para variables y literales simples, y debería funcionar para objetos
toBe() se compara con
===
Básicamente, lo que eso dice es toEqual()
que toBe()
son operadores de Javascripts similares, ===
excepto toBe()
que también se verifica para asegurarse de que sea exactamente el mismo objeto, en el ejemplo siguiente objectOne === objectTwo //returns false
también. Sin embargo, toEqual()
volverá a ser cierto en esa situación.
Ahora, al menos puedes entender por qué cuando se te da:
var objectOne = {
propertyOne: str,
propertyTwo: num
}
var objectTwo = {
propertyOne: str,
propertyTwo: num
}
expect(objectOne).toBe(objectTwo); //returns false
Esto se debe a que, como se indica en esta respuesta a una pregunta diferente, pero similar, el ===
operador en realidad significa que ambos operandos hacen referencia al mismo objeto o, en el caso de tipos de valor, tienen el mismo valor.