Powiedzmy, że mam następujące elementy:
var myNumber = 5;
expect(myNumber).toBe(5);
expect(myNumber).toEqual(5);
Oba powyższe testy przejdą pomyślnie. Czy istnieje różnica pomiędzy toBe()
i toEqual()
jeśli chodzi o ocenę liczb? Jeśli tak, to kiedy powinienem użyć jednego, a nie drugiego?
javascript
jasmine
Lloyd Banks
źródło
źródło
toEqual()
porówna według klucza / wartości-zawartości;toBe()
porówna według odwołania do obiektu.Odpowiedzi:
W przypadku typów pierwotnych (np. Liczb, boolanów, ciągów itp.) Nie ma różnicy między
toBe
itoEqual
; jeden z nich będzie pracować5
,true
albo"the cake is a lie"
.Aby zrozumieć różnicę między
toBe
itoEqual
, wyobraźmy sobie trzy obiekty.Używając ścisłego porównania (
===
), niektóre rzeczy są „takie same”:Ale niektóre rzeczy, nawet jeśli są „równe”, nie są „takie same”, ponieważ reprezentują obiekty, które żyją w różnych miejscach w pamięci.
toBe
Dobieracz Jasmine to nic innego jak opakowanie do ścisłego porównania równościto to samo co
Nie wierz mi na słowo; zobacz kod źródłowy toBe .
Ale
b
ic
reprezentują funkcjonalnie równoważne obiekty; oboje wyglądająCzy nie byłoby wspaniale, gdybyśmy mogli to powiedzieć
b
ic
są „równi”, nawet jeśli nie reprezentują tego samego obiektu?Enter
toEqual
, który sprawdza „głęboką równość” (tzn. Dokonuje rekurencyjnego przeszukiwania obiektów w celu ustalenia, czy wartości ich kluczy są równoważne). Oba następujące testy zostaną zaliczone:Mam nadzieję, że to pomoże wyjaśnić niektóre rzeczy.
źródło
expect(0).toBe(-0)
przejdzie, aleexpect(0).toEqual(-0)
zawiedzie.toBe
używa ścisłej równości - porównuje przez odniesienie,toEqual
używa równoważności właściwości. Zalecane do stosowania wtoEqual
przypadku prymitywówtoEqual
jest o wiele bardziej ostrożny o równości (0 != -0
,"hi" = new String("hi")
itp), więc polecam korzystaniatoEqual
wyłącznie chyba że faktycznie zaniepokojony równoważności odniesienia. Zobacz wszystkie kontrole dokonanetoEqual
weq
metodzie tutaj: github.com/jasmine/jasmine/blob/master/src/core/matchers/…toBe()
versustoEqual()
:toEqual()
sprawdza równoważność.toBe()
z drugiej strony upewnia się, że są dokładnie tym samym obiektem.Powiedziałbym „użyj”
toBe()
przy porównywaniu wartości itoEqual()
przy porównywaniu obiektów.Porównując prymitywne typy
toEqual()
itoBe()
da ten sam wynik. Podczas porównywania obiektówtoBe()
jest bardziej rygorystyczne porównanie, a jeśli nie jest to dokładnie ten sam obiekt w pamięci, zwróci wartość false. Więc jeśli nie chcesz się upewnić, że jest to dokładnie ten sam obiekt w pamięci, użyj gotoEqual()
do porównania obiektów.Sprawdź ten link, aby uzyskać więcej informacji: http://evanhahn.com/how-do-i-jasmine/
Teraz, patrząc na różnicę między
toBe()
itoEqual()
, jeśli chodzi o liczby, nie powinno być żadnej różnicy tak długo, jak to porównanie jest poprawne.5
zawsze będzie równoważne z5
.Miłe miejsce do zabawy i zobaczenia różnych wyników jest tutaj
Aktualizacja
Łatwym sposobem na sprawdzenie
toBe()
itoEqual()
zrozumienie, co dokładnie robią w JavaScript. Według Jasmine API, znaleziono tutaj :Zasadniczo to, co to mówi, jest
toEqual()
itoBe()
jest podobnym===
operatorem Javascripts , oprócz tegotoBe()
sprawdza również, czy jest to dokładnie ten sam obiekt, w tym również w przykładzie poniżejobjectOne === objectTwo //returns false
. JednaktoEqual()
w tej sytuacji zwróci wartość true.Teraz możesz przynajmniej zrozumieć, dlaczego:
expect(objectOne).toBe(objectTwo); //returns false
To dlatego, że, jak wspomniano w tym odpowiedzi na inną, ale podobną pytanie,
===
operator faktycznie oznacza, że oba argumenty odwoływać się do tego samego obiektu, lub w przypadku typów wartości, mają taką samą wartość.źródło
toEqual()
oznacza powiedzenie, żetoEqual()
sprawdza równoważność , ale oczywiste następne pytanie jest w porządku, więc co oznacza „równoważność”? Opis algorytmu zastosowanego do określenia „równoważności” lub co najmniej przykłady przypadków, w których zachowanie siętoEqual()
itoBe()
różni, uczyniłoby to bardziej użytecznym.toEqual
należy używać do głębokiego porównywania obiektów, a nietoBe
. jsfiddle.net/bBL9P/67toEqual
jest taki sam jak .==
expect(1).toEqual('1')
zawodzi, a1 == '1'
jest prawdą.toEqual
nie ma z tym nic wspólnego==
. To tak===
, jakby porównywał obiekty w sposób podobny do porównania wartości.Cytując projekt jaśminowego githuba:
źródło
Analiza kodu źródłowego Jasmine rzuca więcej światła na ten problem.
toBe
jest bardzo prosty i po prostu używa operatora tożsamości / ścisłej równości===
:toEqual
, z drugiej strony, ma prawie 150 linii długości i ma specjalną obsługę wbudowanych obiektów, takich jakString
,Number
,Boolean
,Date
,Error
,Element
iRegExp
. W przypadku innych obiektów rekurencyjnie porównuje właściwości.Jest to bardzo różni się od zachowania operatora równości
==
. Na przykład:źródło
toEqual()
porównuje wartości w przypadku elementu Primitive lub zawartość w przypadku Objects.toBe()
porównuje referencje.Poniższy kod / zestaw powinien być zrozumiały:
źródło
Pomyślałem, że ktoś może polubić wyjaśnienie za pomocą (opatrzonego adnotacjami) przykładu:
Poniżej, jeśli moja funkcja deepClone () wykona swoje zadanie poprawnie, test (jak opisano w wywołaniu „it ()”) zakończy się pomyślnie:
Oczywiście nie jest to kompletny zestaw testów dla mojej funkcji deepClone (), ponieważ nie testowałem tutaj, czy dosłowność obiektu w tablicy (i ta w niej zagnieżdżona) również ma odrębną tożsamość, ale takie same wartości.
źródło
Myślę, że toEqual sprawdza głęboką równość, toBe jest tym samym odniesieniem dla 2 zmiennych
źródło
Punkty do zapamiętania:
toBe()
traktuje porównania jakObject.is()
.toEqual()
traktuje porównania jak===
.Właśnie dlatego dla typów pierwotnych
toBe
itoEqual
nie mają dużej różnicy podczas testowania równości, ale dla typów referencyjnych, takich jak obiekty, wolisz używaćtoEqual
do testowania równości.źródło