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"?


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');
});

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


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;

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


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


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
});

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;


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');

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');
});
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.