Chai: como testar indefinido com a sintaxe 'deveria'

95

Com base neste tutorial que testa um aplicativo angularjs com chai, quero adicionar um teste para um valor indefinido usando o estilo "deveria". Isso falha:

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

com o erro "TypeError: Cannot read property 'should' of undefined", mas o teste passa com o estilo "expect":

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

Como posso fazê-lo funcionar com "deveria"?

thebenedict
fonte
1
É fácil se você usar "assert", você pode fazer comoassert.isUndefined(scope.play(10))
lukaserat

Respostas:

80

Esta é uma das desvantagens da sintaxe deve. Funciona adicionando a propriedade deve a todos os objetos, mas se um valor de retorno ou valor de variável for indefinido, não há um objeto para manter a propriedade.

A documentação fornece algumas soluções alternativas, por exemplo:

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
fonte
14
should.not.existirá validar se o valor for nullentão esta resposta não está correta. @ Daniel tem a resposta a seguir: should.equal(testedValue, undefined);. Essa deve ser a resposta aceita.
Sebastian
7
Eu venho para esta resposta (não a documentação 🙈) em uma base mensal :-)
Ralph Cowling
52
should.equal(testedValue, undefined);

como mencionado na documentação chai

Daniel
fonte
12
omg, o que há para explicar? Você espera que testsValue seja === undefined, então você o testa. Muitos desenvolvedores primeiro colocam testadoValor primeiro e, em seguida, encadea-o com deveria e termina com erro ...
daniel
5
Isso não funciona fora da caixa e não é encontrado na documentação da API para.equal() . Eu posso entender porque @OurManInBananas pediu uma explicação. É um uso inesperado de deveria como uma função que aceita dois argumentos, em vez da forma de método encadeada esperada que aceita um único argumento para o valor esperado. Você só pode conseguir isso importando / exigindo e atribuindo uma versão invocada de .should()conforme descrito na resposta aceita por @DavidNorman e nesta documentação .
gfullam
Acho que você descobrirá que essa .equalsintaxe produz mensagens de erro muito melhores porque permite que você
envie
17

Teste para indefinido

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

Teste para nulo

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

Teste para falso, ou seja, tratado como falso em condições

var should = require('should');
...
should(scope.play(10)).not.be.ok;
Peter Dotchev
fonte
Não é especialmente útil ou intuitivo, mas é inteligente!
thebenedict
2
nao é útil? É a melhor resposta para testes indefinidos no estilo bdd IMO, no entanto, ele precisa instalar outro pacote npm (o pacote deve), e não acho que valha a pena instalar outro pacote apenas para isso, resposta incrível
Wagner Leonardi
16
(typeof scope.play(10)).should.equal('undefined');
teddychan
fonte
8

Tive dificuldade em escrever a instrução deve para testes indefinidos. O seguinte não funciona.

target.should.be.undefined();

Eu encontrei as seguintes soluções.

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

se também pode escrever como uma verificação de tipo

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

Não tenho certeza se o acima é o caminho certo, mas funciona.

De acordo com a postagem do fantasma no github

Viraths
fonte
1
É importante notar que usar essa sintaxe pode resultar em JavaScript interpretando a expressão entre parênteses como uma tentativa de invocar a linha anterior como uma função (se você não estiver terminando as linhas com um ponto e vírgula).
bmacnaughton
5

Experimente isto:

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
fonte
Obrigado, mas é o que estou fazendo na segunda tentativa acima. Eu gostaria de entender como fazer isso com a sintaxe deve .
thebenedict,
1

A resposta de @ david-norman está correta de acordo com a documentação. Tive alguns problemas com a configuração e optei pelo seguinte.

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

Andy Polhill
fonte
typeofoperador retorna uma string ; portanto, essa afirmação não poderia ser aprovada; cuz'undefined' !== undefined
dNitro
1

Não se esqueça da combinação de palavras-chave havee not:

const chai = require('chai');
chai.should();
// ...
userData.should.not.have.property('passwordHash');
Yarovoy
fonte
0

Você pode envolver o resultado da função should()e testar um tipo de "indefinido":

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