Quelle est la difference entre assert, expect et should dans Chai?

161

Quelle est la différence entre assert, expectet should, et quand utiliser quoi?

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

var foo = 'bar';

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

foo.should.equal('bar');
Manu
la source

Réponses:

289

Les différences y sont documentées .

Les trois interfaces présentent différents styles d'assertions d'exécution. En fin de compte, ils effectuent la même tâche. Certains utilisateurs préfèrent un style à l'autre. Cela étant dit, il y a également quelques considérations techniques à souligner:

  1. Les interfaces assert et expect ne se modifient pas Object.prototype, contrairement à ce qu'elles devraient. Ils constituent donc un meilleur choix dans un environnement où vous ne pouvez pas ou ne voulez pas changer Object.prototype.

  2. Les interfaces assert et expect prennent en charge les messages personnalisés à peu près partout. Par exemple:

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

    Le message «toto devrait être vrai» sera affiché avec l'assertion ayant échoué si l'assertion échoue. Vous n'avez pas la possibilité de définir un message personnalisé avec l'interface devrait.

(Note historique: pendant longtemps, cette réponse indiquait que pour obtenir un message personnalisé avec expect, vous deviez utiliser une solution de contournement. Aurélien Ribon m'a informé que passer un message en expecttant que deuxième paramètre fonctionne. Par conséquent, il n'est pas nécessaire de une solution de contournement. Je n'ai pas été en mesure de trouver quelle version de Mocha a commencé à prendre en charge ce message, et je n'ai pas non plus été en mesure de trouver quelle version de la documentation l'a documenté pour la première fois.)

Notez que assert.isTrue(foo), expect(foo).to.be.trueet foo.should.be.truetous affichent les éléments suivants si vous n'utilisez pas de message personnalisé, et foo === 1:

    AssertionError: expected 1 to be true

Ainsi, bien que les interfaces expect et should soient plus agréables à lire , ce n'est pas comme si une interface était plus naturellement informative que l'autre lorsqu'une assertion échoue. Ce message, qui est identique pour les trois interfaces, ne vous dit pas exactement ce que vous testiez, mais seulement que la valeur que vous avez obtenue était 1mais que vous vouliez true. Si vous voulez savoir ce que vous testez, vous devez ajouter un message.

Louis
la source
8
Notez que vous pouvez également faireexpect(foo).to.equal(true, "foo should be true");
user5325596
Je ne peux pas faire apparaître de message personnalisé avec expectla dernière version de mocha
Mirko
@Mirko La version de Mocha n'est pas ce qui est critique ici. Utilisez-vous le dernier Chai?
Louis
Idem pour moi, sur un projet vanilla express (4.16.3), mocha (5.1.1), chai (4.1.2), chai-http (4.0.0). Le message personnalisé n'apparaît nulle part lorsqu'il est exécuté avec la commande mochaet que le test échoue.
Juha Untinen
15

J'espère que ces exemples simples clarifient leurs différences

Affirmer

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

Dans tous les cas, le style assert vous permet d'inclure un message facultatif comme dernier paramètre dans l'instruction assert. Ceux-ci seront inclus dans les messages d'erreur si votre assertion échoue.

Notez que expect et should utilisent un langage chaînable pour construire des assertions, mais ils diffèrent dans la façon dont une assertion est initialement construite. Dans le cas de devrait, il existe également des mises en garde et des outils supplémentaires pour surmonter les mises en garde.

Attendre

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

Expect vous permet d'inclure des messages arbitraires à ajouter à toute affirmation échouée qui pourrait se produire.

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

Ceci est pratique lorsqu'il est utilisé avec des sujets non descriptifs tels que les booléens ou les nombres.

Devrait

Le style should permet les mêmes assertions chaînables que l'interface expect, mais il étend chaque objet avec une propriété should pour démarrer votre chaîne. Ce style présente quelques problèmes lorsqu'il est utilisé avec Internet Explorer, alors soyez conscient de la compatibilité du navigateur.

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

Différences entre s'attendre et devrait

Tout d'abord, notez que le expect require est juste une référence à la fonction expect, alors qu'avec le should require, la fonction est en cours d'exécution.

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

L' interface expect fournit une fonction comme point de départ pour enchaîner vos assertions de langage. Cela fonctionne sur node.js et dans tous les navigateurs.

L' interface should étend Object.prototype pour fournir un seul getter comme point de départ pour vos assertions de langage. Il fonctionne sur node.js et dans tous les navigateurs modernes sauf Internet Explorer.

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