Digamos que tengo lo siguiente:
var myNumber = 5;
expect(myNumber).toBe(5);
expect(myNumber).toEqual(5);
Ambas pruebas anteriores pasarán. ¿Hay 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?
javascript
jasmine
Lloyd Banks
fuente
fuente
toEqual()
se comparará por clave / valores-contenido;toBe()
se comparará por referencia de objeto.Respuestas:
Para los tipos primitivos (por ejemplo, números, booleanos, cadenas, etc.), no hay diferencia entre
toBe
ytoEqual
; o bien se trabajará para5
,true
o"the cake is a lie"
.Para entender la diferencia entre
toBe
ytoEqual
, imaginemos tres objetos.Usando una comparación estricta (
===
), algunas cosas son "iguales":Pero algunas cosas, aunque son "iguales", no son "lo mismo", ya que representan objetos que viven en diferentes lugares en la memoria.
El
toBe
comparador de Jasmine no es más que un envoltorio para una estricta comparación de igualdades lo mismo que
No solo confíes en mi palabra; vea el código fuente de toBe .
Pero
b
yc
representan objetos funcionalmente equivalentes; ambos se ven como¿No sería genial si pudiéramos decir eso
b
yc
ser "iguales" incluso si no representan el mismo objeto?Enter
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). Ambas pruebas pasarán:Espero que ayude a aclarar algunas cosas.
fuente
expect(0).toBe(-0)
pasará peroexpect(0).toEqual(-0)
fallará.toBe
usa igualdad estricta - compara por referencia,toEqual
usa equivalencia de propiedad. Recomendado para usartoEqual
en primitivastoEqual
es mucho más cuidado con la igualdad (0 != -0
,"hi" = new String("hi")
, etc.), así que me gustaría recomendar el usotoEqual
en exclusiva a menos que estés realmente preocupados por la equivalencia de referencia. Vea todos los controles realizadostoEqual
en eleq
método aquí: github.com/jasmine/jasmine/blob/master/src/core/matchers/…toBe()
versustoEqual()
:toEqual()
verifica la equivalencia.toBe()
, por otro lado, se asegura de que sean exactamente el mismo objeto.Yo diría usar
toBe()
cuando se comparan valores ytoEqual()
cuando se comparan objetos.Al comparar tipos primitivos,
toEqual()
ytoBe()
dará 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, esto devolverá falso. Entonces, a menos que desee asegurarse de que sea exactamente el mismo objeto en la memoria, utilícelotoEqual()
para comparar objetos.Consulte este enlace para obtener más información: http://evanhahn.com/how-do-i-jasmine/
Ahora, al observar la diferencia entre
toBe()
ytoEqual()
cuando se trata de números, no debería haber ninguna diferencia siempre que su comparación sea correcta.5
siempre será equivalente a5
.Un buen lugar para jugar con esto para ver diferentes resultados está aquí
Actualizar
Una manera fácil de ver
toBe()
ytoEqual()
entender es qué hacen exactamente en JavaScript. Según la API de Jasmine, que se encuentra aquí :Esencialmente, lo que está diciendo es
toEqual()
ytoBe()
es un===
operador Javascripts similar , exceptotoBe()
que también se está verificando para asegurarse de que sea exactamente el mismo objeto, en eso también para el ejemplo a continuaciónobjectOne === objectTwo //returns false
. Sin embargo,toEqual()
volverá cierto en esa situación.Ahora, al menos puede entender por qué cuando se le da:
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.fuente
toEqual()
hace al decir quetoEqual()
verifica la equivalencia , pero la siguiente pregunta obvia está bien, entonces, ¿qué significa "equivalente"? Una descripción del algoritmo utilizado para determinar la "equivalencia", o al menos ejemplos de casos en los que el comportamientotoEqual()
y latoBe()
diferencia, lo haría más útil.toEqual
debe usarse para una comparación profunda entre objetos, notoBe
. jsfiddle.net/bBL9P/67toEqual
es lo mismo que==
.expect(1).toEqual('1')
falla, mientras que1 == '1'
es cierto.toEqual
no tiene nada que ver con==
. Es como,===
excepto que comparará objetos de una manera similar a la comparación por valor.Para citar el proyecto jazmín github,
fuente
Mirando el código fuente de Jasmine arroja más luz sobre el tema.
toBe
es muy simple y solo usa el operador de identidad / igualdad estricta===
:toEqual
Por otra parte, es casi 150 líneas de largo y tiene un manejo especial para la construcción de objetos comoString
,Number
,Boolean
,Date
,Error
,Element
yRegExp
. Para otros objetos compara recursivamente propiedades.Esto es muy diferente del comportamiento del operador de igualdad,
==
. Por ejemplo:fuente
toEqual()
compara valores si es Primitivo o contenidos si es Objetos.toBe()
compara referencias.El siguiente código / suite debe explicarse por sí mismo:
fuente
Pensé que a alguien le gustaría una explicación con un ejemplo (anotado):
A continuación, si mi función deepClone () hace su trabajo correctamente, la prueba (como se describe en la llamada 'it ()' tendrá éxito:
Por supuesto, este no es un conjunto de pruebas completo para mi deepClone (), ya que no he probado aquí si el objeto literal en la matriz (y el anidado allí) también tiene una identidad distinta pero los mismos valores.
fuente
Creo que toEqual está comprobando la igualdad profunda, toBe es la misma referencia de 2 variables
fuente
Puntos a tener en cuenta:
toBe()
trata las comparaciones como loObject.is()
hace.toEqual()
trata las comparaciones como lo===
hace.Es por eso que para los tipos primitivos,
toBe
ytoEqual
no tienen mucha diferencia al probar la igualdad, pero para los tipos de referencia como los objetos, preferiría usartoEqual
para probar la igualdad.fuente