Chai: jak sprawdzić wartość undefined za pomocą składni „powinien”

96

Opierając się na tym samouczku testującym aplikację angularjs z chai, chcę dodać test dla niezdefiniowanej wartości przy użyciu stylu „powinien”. To się nie udaje:

it ('cannot play outside the board', function() {
  scope.play(10).should.be.undefined;
});

z błędem „TypeError: Cannot read property„ should ”of undefined”, ale test przechodzi ze stylem „Expect”:

it ('cannot play outside the board', function() {
  chai.expect(scope.play(10)).to.be.undefined;
});

Jak sprawić, by działało z „powinien”?

benedykt
źródło
1
To proste, jeśli użyjesz „assert”, możesz to zrobić tak, jakassert.isUndefined(scope.play(10))
lukaserat

Odpowiedzi:

80

Jest to jedna z wad składni powinna. Działa poprzez dodanie właściwości should do wszystkich obiektów, ale jeśli wartość zwracana lub wartość zmiennej jest niezdefiniowana, nie ma obiektu, który mógłby ją przechowywać.

Dokumentacja daje pewne obejścia, na przykład:

var should = require('chai').should();
db.get(1234, function (err, doc) {
  should.not.exist(err);
  should.exist(doc);
  doc.should.be.an('object');
});
David Norman
źródło
14
should.not.existsprawdzi, czy wartość jest nulltaka, ta odpowiedź jest nieprawidłowa. @daniel ma odpowiedź poniżej: should.equal(testedValue, undefined);. To powinna być akceptowana odpowiedź.
Sebastian
7
Przychodzę do tej odpowiedzi (nie do dokumentów 🙈) co miesiąc :-)
Ralph Cowling
54
should.equal(testedValue, undefined);

jak wspomniano w dokumentacji chai

daniel
źródło
12
omg, co tu jest do wyjaśnienia? Oczekujesz, że wartość testowana wartość === nieokreślona, ​​więc ją testujesz. Wielu programistów najpierw umieszcza testową wartość jako pierwszą, a następnie łączy ją z powinien, a kończy się to błędem ...
daniel
5
To nie działa po wyjęciu z pudełka i nie ma go w dokumentacji interfejsu API dla.equal() . Rozumiem, dlaczego @OurManInBananas poprosił o wyjaśnienie. Jest to nieoczekiwane użycie powinno jako funkcji przyjmującej dwa argumenty, zamiast oczekiwanej postaci metody łańcuchowej akceptującej pojedynczy argument dla oczekiwanej wartości. Możesz to osiągnąć tylko poprzez zaimportowanie / wymaganie i przypisanie wywoływanej wersji programu, .should()jak opisano w zaakceptowanej odpowiedzi @DavidNorman oraz w tej dokumentacji .
gfullam
Myślę, że przekonasz się, że ta .equalskładnia generuje znacznie lepsze komunikaty o błędach, ponieważ pozwala wyświetlać komunikaty, które są bardziej opisowe, gdy coś się nie powiedzie
jcollum
17

Testuj na niezdefiniowane

var should = require('should');
...
should(scope.play(10)).be.undefined;

Sprawdź, czy nie ma wartości null

var should = require('should');
...
should(scope.play(10)).be.null;

Test pod kątem fałszu, tj. Traktowany jako fałszywy w warunkach

var should = require('should');
...
should(scope.play(10)).not.be.ok;
Peter Dotchev
źródło
Niezbyt przydatne ani intuicyjne, ale to sprytne!
thebenedict
2
nieużyteczny? To najlepsza odpowiedź na niezdefiniowane testy w IMO w stylu bdd, jednak wymaga zainstalowania innego pakietu npm (pakiet powinien) i nie sądzę, że warto instalować inny pakiet tylko po to, jednak świetna odpowiedź
Wagner Leonardi
16
(typeof scope.play(10)).should.equal('undefined');
teddychan
źródło
8

Starałem się napisać instrukcję powinności dla niezdefiniowanych testów. Poniższe nie działa.

target.should.be.undefined();

Znalazłem następujące rozwiązania.

(target === undefined).should.be.true()

if może również zapisać to jako kontrolę typu

(typeof target).should.be.equal('undefined');

Nie jestem pewien, czy powyższe jest właściwą drogą, ale działa.

Według posta z ghosta na githubie

Viraths
źródło
1
Warto zauważyć, że użycie tej składni może spowodować, że JavaScript zinterpretuje wyrażenie w nawiasach jako próbę wywołania poprzedniego wiersza jako funkcji (jeśli nie kończysz wierszy średnikiem).
bmacnaughton,
5

Spróbuj tego:

it ('cannot play outside the board', function() {
   expect(scope.play(10)).to.be.undefined; // undefined
   expect(scope.play(10)).to.not.be.undefined; // or not
});
EpokK
źródło
Dzięki, ale to właśnie robię w drugiej próbie powyżej. Chciałbym zrozumieć, jak to zrobić za pomocą składni powinna .
thebenedict
2

Nie zapomnij o kombinacji słów kluczowych havei not:

const chai = require('chai');
chai.should();
// ...
userData.should.not.have.property('passwordHash');
Yarovoy
źródło
1

Odpowiedź @ david-norman jest poprawna zgodnie z dokumentacją, miałem kilka problemów z konfiguracją i zamiast tego zdecydowałem się na następujące.

(typeof scope.play (10)). should.be.undefined;

Andy Polhill
źródło
typeofoperator zwraca ciąg ; więc tego twierdzenia nie można było przekazać; bo'undefined' !== undefined
dNitro
0

Możesz opakować wynik funkcji should()i przetestować go pod kątem typu „undefined”:

it ('cannot play outside the board', function() {
  should(scope.play(10)).be.type('undefined');
});
pegli
źródło