文章目录
-
- vue项目单元测试编写-chai
- 开始
-
- 为什么使用断言库
- 使用
- BDD风格API
-
- 自然语句
- a(String type[, String errMsg])
- .not
- equal(Any val[, String errMsg])
- eql(Any val[, String errMsg])
- above&least&below&most
- within(Number start, Number finish[, String errMsg])
- instanceof(Constructor consturctor[, String errMsg])
- property(String name[, Any val, String errMsg])
- ownPropertyDescriptor(String name[, Object descriptor, String errMsg])
- lengthOf(Number len[, String errMsg])
- match(RegExp reg[, String errMsg])
- string(String str[, String, errMsg])
- include
- keys(key1, key2[, ...])
- throw()
- respondTo(String method[, String errMsg])
- itself
- satisfy(Function matcher[, String msg])
- .closeTo(Number expe, Number delta[, String errMsg])
- members(Array set[, String errMsg])
- oneOf(Array list[, String errMsg])
- change,increase,decrease
- by(Number delta[, String errMsg])
- finite
- fail(actual, expected, message, operator)
- extensible&sealed&frozen
- deep
- nested
- own
- ordered
- any和all
- .ok&.true&.false&.null&.undefined&.NaN
- exist
- empty
- 备注:API风格的错误信息
- 注意
- 参考
vue项目单元测试编写-chai
我们在测试时需要针对数据以及程序做一个预期,当程序的结果不是我们所预期的那样时,他会帮我们中断程序,并抛出一个错误,以便我们更好的对程序进行调试。
使用版本
4.x
开始
为什么使用断言库
因为mocha没有自己的断言库,所以需要第三方的断言库。而断言在我们单元测试中是必不可少的,他可以帮我们在某一个地方对程序的值,类型,结果等做出一系列的假设,当程序不符合预期时,他可以抛出一个错误来中断我们的测试,这样我们可以及时定位问题所在。比如:
// sum.js
export const sum = (x, y) => {
return x + y;
}
// example.spec.js
import {
sum } from 'sum.js';
describe('myTest', function() {
it('测试一', function () {
// 对sum函数的调用结果进行断言
if (sum(1, 2) !== 3) {
// 只要程序抛出一个错误,mocha就会认为测试不通过
throw new Error('sum函数执行不符合预期');
}
});
});
上面的例子中,我们对一个加法函数sum进行测试,并且在测试用例中,对他的调用结果进行了断言,预期sum(1, 2)
的结果为3
,如果结果是正确的,那么测试会通过,如果其函数调用结果不符合我们的预期结果,那么就会抛出一个错误,这样,我们的这个测试用例就不会通过。
使用
基本使用
我们上面的例子中也使用了断言对函数结果进行了预期,但是这么写第一点就是比较麻烦,因为你在编写测试时,务必需要进行大量类似的判断,来测试程序中可能会出错的地方,那么每个地方都这样写,那就很冗余了。第二点就是这么写可能一样看上去代码比较混乱,并且代码所表达的意图也没有那么的“一目了然”。
这时候,断言库就派上用场了。他的简单使用如下:
// sum.js
export const sum = (x, y) => {
return x + y;
}
// example.spec.js
// 引入chai中的expect函数,其作用就是用于断言的函数
import {
expect } from 'chai';
import {
sum } from 'sum.js';
// 在describe中编写
describe('myTest', function() {
it('测试二', function () {
// 不符合预期的断言
expect(sum(1, 2)).equal(4);
});
})
结果:
1 failing
1) myTest
测试二:
AssertionError: expected 3 to equal 4
+ expected - actual
-3
+4
at Context. (dist\webpack:\tests\unit\example.spec.js:24:1)
我们故意对sum函数预期了一个错误的值,所以我们的测试结果并没有通过,我们可以看到,chai中的expect断言函数他帮我们封装了错误异常处理,在我们给出的预期值和程序的实际值不一致时,他自动帮我们抛出异常让测试单元不通过,并且我们从结果来看,他对错误进行了更加详细的描述,并给出了我们的预期值和实际值,让我们更好的定位问题。而且他还有一个好处,那就是chai支持三种断言风格以便我们更好的进行选择。
断言风格
chai支持三种断言风格:
其中包含TDD风格断言assert以及BDD风格两种断言:should和expect,他的简单使用如下:
assert
// 判断是否相等
const foo = 'bar';
assert.equal(foo, 'bar', 'foo equal `bar`');
should
const foo = 'bar';
foo.should.equal('bar');
expect
const foo = 'bar';
expect(foo).to.equal('bar');
assert风格的这里暂且不说,这里主要使用expect为主,BDD风格中的expect和should风格的断言,他们都可以使用一种类似于自然语言的方式对断言进行描述,他们都支持一种链式语法构造你的断言,他们区别主要在于语法上,而should在某些情况下使用会有一些问题,我们来看为什么,如下例子:
// 引入expect和should函数
const {
expect, should } from 'chai';
const foo = 'bar';
// should风格
foo.should.be.a('string');
foo.should.equal('bar');
// expect风格
expect(foo).to.be.a('string');
expect(foo).to.equal('bar');
使用should风格时只需要引入should函数,使用expect风格时只需要引入expect函数即可。上面的例子中,expect和should在写法上有所不同,should类似于:foo应该是一个字符串,foo应该是等于bra
,而expect风格则类似于:我预期foo变量是一个字符串,我预期foo的值等于bar
。大概就是这么个区别,他们都可以使用类似的自然语法构造你的断言,比如be,to
这些,后续会进行介绍。而在使用should时,各位应该注意:
should是通过实例化对象原型进行断言,所以,他在一些情况可能不会工作(比如值时undefined的时候就不能用它,你总不能:undefined.should...吧),而且据说他在ie下会有些问题,所以,使用expect会更好一些。
BDD风格API
expect和should他们都有类似的语法风格,只不过他们在构造断言的方式上有所不同,所以,api都是类似的。以下会列举一些常用的api,不是所有的。具体api请参考官网:https://www.chaijs.com/api/bdd/
下文中的用例代码:指代下文使用的sum函数
// sum.js
export const sum = (x, y) => {
return x + y;
}
自然语句
这里的自然语句是指为了提高你的断言的可读性所增加的链式结构语句,仅仅为了提高断言的可读性,没有特殊的作用。
- to
- be
- been
- is
- that
- which
- and
- has
- have
- with
- at
- of
- same
- but
- does
- still
英语好点的,应该都大致明白他们是干啥的,这里就不多说了,反正我英语比较烂。
a(String type[, String errMsg])
断言目标的类型是type
,注意,type
的开头是小写的
expect('foo').to.be.a('string');
expect({
a: 1}).to.be.an('object');
expect(null).to.be.a('null');
expect(undefined).to.be.an('undefined');
expect(new Error).to.be.an('error');
expect(Promise.resolve()).to.be.a('promise');
expect(