Qual é a diferença entre assert, expect e should in Chai?

159

Qual é a diferença entre assert, expecte should, e quando usar o quê?

assert.equal(3, '3', '== coerces values to strings');

var foo = 'bar';

expect(foo).to.equal('bar');

foo.should.equal('bar');
Manu
fonte

Respostas:

288

As diferenças estão documentadas lá .

As três interfaces apresentam estilos diferentes de execução de asserções. Por fim, eles executam a mesma tarefa. Alguns usuários preferem um estilo ao outro. Dito isto, há também algumas considerações técnicas que merecem destaque:

  1. As interfaces assert e expect não modificam Object.prototype, ao passo que deveriam. Portanto, eles são uma escolha melhor em um ambiente em que você não pode ou não quer mudar Object.prototype.

  2. As interfaces assert e expect suportam mensagens personalizadas em qualquer lugar. Por exemplo:

    assert.isTrue(foo, "foo should be true");
    expect(foo, "foo should be true").to.be.true;

    A mensagem "foo deveria ser verdadeira" será exibida junto com a asserção com falha se a asserção falhar. Você não tem a oportunidade de definir uma mensagem personalizada com a interface should.

(Nota histórica: por um longo tempo, esta resposta afirmou que, para receber uma mensagem personalizada expect, você teria que usar uma solução alternativa. Aurélien Ribon me informou que passar uma mensagem para o expectsegundo parâmetro funciona. Consequentemente, não há necessidade de uma solução alternativa. Não consegui descobrir qual versão do Mocha começou a fornecer suporte para esta mensagem, nem consegui descobrir qual versão da documentação a documentou pela primeira vez.)

Observe que assert.isTrue(foo), expect(foo).to.be.truee foo.should.be.truetodos geram o seguinte, se você não usar uma mensagem personalizada, e foo === 1:

    AssertionError: expected 1 to be true

Portanto, enquanto a interface expect e deveria ser mais agradável de ler , não é como se uma interface fosse mais informativa do que a outra quando uma afirmação falha. Esta mensagem, que é idêntica para todas as três interfaces, não informa exatamente o que você estava testando, apenas que o valor que você obteve foi 1mas queria true. Se você quiser saber o que estava testando, precisará adicionar uma mensagem.

Louis
fonte
8
Note que você também pode fazerexpect(foo).to.equal(true, "foo should be true");
user5325596
Não consigo exibir nenhuma mensagem personalizada expectusando a versão mais recente do mocha #
Mirko
@ Mirko A versão do Mocha não é o que é crítico aqui. Você está usando o mais recente Chai?
Louis
O mesmo para mim, em um projeto vanilla express (4.16.3), mocha (5.1.1), chai (4.1.2), chai-http (4.0.0). A mensagem personalizada não aparece em nenhum lugar quando executada com o comando mochae recebendo uma falha de teste.
Juha Untinen
15

Espero que esses exemplos simples deixem suas diferenças claras

Afirmar

var assert = require('chai').assert
, foo = 'bar'
, beverages = { tea: [ 'chai', 'matcha', 'oolong' ] };

assert.typeOf(foo, 'string'); // without optional message
assert.typeOf(foo, 'string', 'foo is a string'); // with optional message
assert.equal(foo, 'bar', 'foo equal `bar`');
assert.lengthOf(foo, 3, 'foo`s value has a length of 3');
assert.lengthOf(beverages.tea, 3, 'beverages has 3 types of tea');

Em todos os casos, o estilo assert permite incluir uma mensagem opcional como o último parâmetro na declaração assert. Eles serão incluídos nas mensagens de erro, caso sua afirmação não seja aprovada.

Observe expect e deveria usar linguagem encadeada para construir afirmações, mas elas diferem na maneira como uma afirmação é inicialmente construída. No caso de should, também existem algumas advertências e ferramentas adicionais para superar as advertências.

Espero

var expect = require('chai').expect
, foo = 'bar'
, beverages = { tea: [ 'chai', 'matcha', 'oolong' ] };
expect(foo).to.be.a('string');
expect(foo).to.equal('bar');
expect(foo).to.have.lengthOf(3);
expect(beverages).to.have.property('tea').with.lengthOf(3);

O Expect permite incluir mensagens arbitrárias para anexar previamente a quaisquer afirmações com falha que possam ocorrer.

var answer = 43;

// AssertionError: expected 43 to equal 42.
expect(answer).to.equal(42);

// AssertionError: topic [answer]: expected 43 to equal 42.
expect(answer, 'topic [answer]').to.equal(42);

Isso é útil quando usado com tópicos não descritivos, como booleanos ou números.

Devemos

O estilo should permite as mesmas asserções encadeadas que a interface de espera, no entanto, estende cada objeto com uma propriedade should para iniciar sua cadeia. Esse estilo apresenta alguns problemas quando usado com o Internet Explorer, portanto, esteja ciente da compatibilidade do navegador.

var should = require('chai').should() //actually call the function
, foo = 'bar'
, beverages = { tea: [ 'chai', 'matcha', 'oolong' ] };

foo.should.be.a('string');
foo.should.equal('bar');
foo.should.have.lengthOf(3);
beverages.should.have.property('tea').with.lengthOf(3);

Diferenças entre esperar e deve

Primeiro, observe que o requisito de espera é apenas uma referência à função de espera, enquanto que com o requisito de dever, a função está sendo executada.

var chai = require('chai')
, expect = chai.expect
, should = chai.should();

A interface expect fornece uma função como ponto de partida para encadear suas asserções de idioma. Ele funciona no node.js e em todos os navegadores.

A interface should estende o Object.prototype para fornecer um único getter como ponto de partida para suas asserções de idioma. Ele funciona no node.js e em todos os navegadores modernos, exceto no Internet Explorer.

Adépòjù Olúwáségun
fonte