179

assert,expect和 和有什么区别should?什么时候用什么?

assert.equal(3, '3', '== coerces values to strings');
    
var foo = 'bar';
    
expect(foo).to.equal('bar');
    
foo.should.equal('bar');
4

3 回答 3

301

差异记录在那里

这三个接口呈现了不同风格的执行断言。最终,他们执行相同的任务。一些用户更喜欢一种风格而不是另一种风格。话虽如此,还有一些技术考虑值得强调:

  1. 和接口不修改,assert而。因此,在您无法或不想改变的环境中,它们是更好的选择。expectObject.prototypeshouldObject.prototype

  2. 和接口几乎在任何地方assertexpect支持自定义消息。例如:

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

如果断言失败,则消息“foo should be true”将与失败的断言一起输出。您没有机会使用should界面设置自定义消息。

(历史记录:很长一段时间以来,这个答案都表明要使用 获取自定义消息expect,您必须使用解决方法。Aurélien Ribon告诉我,将消息expect作为第二个参数传递是有效的。因此,不需要一种解决方法。我无法找到哪个版本的 Mocha 开始为该消息提供支持,也无法找到第一次记录它的文档的哪个版本。)

请注意,assert.isTrue(foo)如果您不使用自定义消息,所有输出以下内容,expect(foo).to.be.true并且:foo.should.be.truefoo === 1

    AssertionError: expected 1 to be true

因此,虽然expectandshould接口更易于阅读,但当断言失败时,并不是一个接口比另一个接口更自然地提供信息。此消息对于所有三个接口都是相同的,它并没有告诉您到底在测试什么,只是告诉您得到的值是1but you want true。如果你想知道你在测试什么,你需要添加一条消息。

于 2014-01-28T12:01:03.323 回答
24

我希望这个简单的例子能清楚地说明它们的区别

断言

var assert = require('chai').assert
const foo = 'bar'
const 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');

在所有情况下,断言样式都允许您在断言语句中包含可选消息作为最后一个参数。如果您的断言未通过,这些将包含在错误消息中。

注意 expectshould使用可链接的语言来构造断言,但它们在断言最初构造的方式上有所不同。在 的情况下should,还有一些警告和额外的工具可以克服这些警告。

预计

var expect = require('chai').expect
const foo = 'bar'
const 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允许您在任何可能发生的失败断言之前包含任意消息。

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

这在与非描述性主题(例如布尔值或数字)一起使用时会派上用场。

应该

should样式允许与期望接口相同的可链接断言,但是它使用 should 属性扩展每个对象以启动您的链。此样式在与 Internet Explorer 一起使用时存在一些问题,因此请注意浏览器兼容性。

var should = require('chai').should() //actually call the function
const foo = 'bar'
const 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);

期望和应该的区别

首先,请注意expectrequire 只是对expect函数的引用,而使用shouldrequire 时,函数正在执行。

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

expect接口提供了一个函数作为链接语言断言的起点。它适用于 node.js 和所有浏览器。

should接口扩展了 Object.prototype 以提供单个 getter 作为语言断言的起点。它适用于 node.js 和除 Internet Explorer 之外的所有现代浏览器。

于 2018-09-12T16:00:48.237 回答
0

如果我错了,请纠正我,但在代码运行行为方面,断言和期望之间也存在巨大差异。断言应该在错误时停止程序。期望不是。

于 2022-01-25T00:37:43.320 回答