Node assert 的用法

6,196 阅读6分钟

Node assert 的用法


assert模块提供了断言测试的函数,用于测试不变式 有strict和legacy两种模式,建议只使用strict模式

1. 判断值是否为真值
  • assert(value[, message])
const assert = require('assert')
assert('123', '第一个参数为false时,会抛出错误!')
assert(true, '第一个值为false时, 错误信息抛出')
//pass

当assert函数的第一个参数为true时,通过断言测试,第二个参数不会显示;

assert(false, '第一个值为false时, 错误信息抛出')
//AssertionError [ERR_ASSERTION]: 第一个值为false时, 错误信息抛出

而当assert函数的第一个参数为false时,第二个参数(即具体报错信心)则会显示。

  • assert.ok(value[, message])

assert是assert.ok() 的别名。两者作用一模一样,都是判断值是否为真值。

const assert = require('assert')
assert.ok(true)
assert.ok('false')
//pass
assert.ok(0, '不是真值,抛出错误!')
//AssertionError [ERR_ASSERTION]: 不是真值,抛出错误!

上述代码中, 0 === true 为false,所以不是真值,显示第二个参数为报错信息。

2. 判断预期值和实际值相等(==)
  • assert.equal(actual, expected[, message])

这个函数用来比较实际值是否与期望值相符,第一二个参数分别为实际值和期望值,第三个参数为当实际值与期望值比较为false时,显示的报错信息。

cosnt aseert = require('assert')
assert.equal(1, '1', '实际值与期望值比较为false')
assert.equal(1+1, '2', '实际值与期望值比较为false')
//pass

实际上,assert.equal()实现的时不严格比较(==),只比较值(基本类型)或者对值得引用(引用类型)是否相等,不比较类型是否相等。

基本类型比较:

assert.equal(0, 1, '实际值与期望值比较为false')
//AssertionError [ERR_ASSERTION]: 实际值与期望值比较为false 

引用类型比较:

assert.equal({}, {}, '看似相同得两个引用类型变量实则,有不同得引用,因此相比为false')
//看似相同得两个引用类型变量实则,有不同得引用,因此相比为false  
  • assert.deepEqual(actual, expected[, message])

这个函数与assert.equal()作用类似(==),但是与equal不同的是,它在对引用类型进行比较的时候,不是对值的引用进行比较,而是比较的对象的属性值

const assert = require('assert')
assert.deepEqual([1,2,3], [1,2,3], '引用类型属性不同')
//pass
assert.deepEqual([1,2,3], [1,2,3,4], '引用类型属性不同')
//AssertionError [ERR_ASSERTION]: 引用类型属性不同
3. 判断预期值和实际值全等(===)
  • assert.strictEqual(actual, expected[, message])

strictEqual是严格等于,在比较值或者对值得引用外,还要比较类型。

const assert = require('assert')
assert.strictEqual(1, 1);
// 测试通过。
assert.strictEqual(1, '1');
// AssertionError [ERR_ASSERTION]: 1 === '1'
  • assert.deepStrictEqual(actual, expected[, message])

这个函数其实也很好理解,与上一节相比,这里时三等号,代表着严格相等。

对基本类型,在类型相等的同时,值也要相等

const assert = require('assert')
assert.deepStrictEqual(1, 0.5+0.5, "对基本类型,在类型相等的同时,值也要相等 ")
//pass
assert.deepStrictEqual(1, '1', "对基本类型,在类型相等的同时,值也要相等 ") 
//AssertionError [ERR_ASSERTION]: 对基本类型,在类型相等的同时,值也要相等

对引用类型,在引用相等的同时,内部属性也要相等

const a = {b:1, c:2}, 
      d = a,
      e = Object.create({b:1, c:2});

assert.deepStrictEqual(a, d, "对引用类型,在引用相等的同时,内部属性也要相等") 
//pass
assert.deepStrictEqual(a, e, "对引用类型,在引用相等的同时,内部属性也要相等") 
//AssertionError [ERR_ASSERTION]: 对引用类型,在引用相等的同时,内部属性也要相等
4. 判断预期值和实际值不相等及严格不相等
  • assert.notEqual(actual, expected[, message])
assert.notEqual("1", "2");
// 断言通过
assert.notEqual("1", 2);
// 断言通过
assert.notEqual("1", 1);
// AssertionError [ERR_ASSERTION]: '1' != 1
  • assert.notDeepEqual(actual, expected[, message])
const obj1 = { a: "foo" },
    obj2 = { b: "bar" },
    obj3 = Object.create(obj1);
assert.notDeepEqual(obj1,obj1,'actual equal to expected');
// AssertionError [ERR_ASSERTION]: actual equal to expected
assert.notDeepEqual(obj1,obj2,'actual equal to expected');
// 断言通过
assert.notDeepEqual(obj1,obj3,'actual equal to expected');
// 断言通过
  • assert.notStrictEqual(actual, expected[, message])
assert.notStrictEqual("1", 1);
// 断言通过
assert.notStrictEqual("1", "1");
// AssertionError [ERR_ASSERTION]: '1' !== '1'
  • assert.notDeepStrictEqual(actual, expected[, message])
assert.notDeepStrictEqual({ a: '1' }, { a: 1 });
//断言通过
assert.notDeepStrictEqual({ a: '1' }, { a: "1" });
//AssertionError [ERR_ASSERTION]: { a: '1' } notDeepStrictEqual { a: '1' }

以上四个接口的通过条件与上述对应api相反,只要是不相等测试就通过,如果比较结果为true就会报错

5. 断言错误并抛出
  • assert.fail(message)

直接报错

assert.fail('报错')
//AssertionError [ERR_ASSERTION]: 报错
  • assert.throws(fn[, error][, message])

如果fn抛出的错误满足error参数,也就是抛出错误与期望d的错误一致,则断言通过,否则抛出fn中的错误,如果fn不抛出错误,则抛出AssertionError

参数说明:

  • fn Function
  • error RegExp | Function | Object | Error
  • message String
const err = new TypeError('错误值');
err.code = 404;
err.foo = 'bar';
err.info = {
  nested: true,
  baz: 'text'
};
err.reg = /abc/i;

assert.throws(
  () => {
    throw err;
  },
  {
    name: 'TypeError',
    message: '错误值'
    info: {
      nested: true,
      baz: 'text'
    }
    // 注意,将仅测试验证对象上的属性。
    // 使用嵌套对象需要存在所有属性。
    // 否则验证将失败。
  }
);

// 使用正则表达式验证错误属性:
assert.throws(
  () => {
    throw err;
  },
  {
    // `name` 和 `message` 属性是字符串,使用正则表达式将匹配字符串。 
    // 如果失败,则会抛出错误。
    name: /^TypeError$/,
    message: /错误/,
    foo: 'bar',
    info: {
      nested: true,
      // 无法对嵌套属性使用正则表达式!
      baz: 'text'
    },
    // `reg` 属性包含一个正则表达式,
    // 并且只有当验证对象包含相同的正则表达式时,
    // 它才会通过。
    reg: /abc/i
  }
);

// 由于 `message` 和 `name` 属性不同而失败:
assert.throws(
  () => {
    const otherErr = new Error('未找到');
    otherErr.code = 404;
    throw otherErr;
  },
  err // 测试 `message`、 `name` 和 `code`。
);
  • assert.doesNotThrow(block, error, message)

使用 assert.doesNotThrow() 实际上没有用处,因为捕获错误然后重新抛出它没有任何好处。 应该考虑在不应抛出错误的特定代码路径旁边添加注释,并尽可能保留错误消息。

当调用 assert.doesNotThrow() 时,它将立即调用 fn 函数。

如果抛出错误并且它与 error 参数指定的类型相同,则抛出 AssertionError。 如果错误的类型不同,或者 error 参数未定义,则错误将传播回调用方。

如果指定,则 error 可以是 Class、RegExp 或验证函数。 有关更多详细信息,请参见 assert.throws()。

assert.doesNotThrow(
  () => {
    throw new TypeError('错误信息');
  },
  TypeError,
  '抛出错误'
);
// 抛出 AssertionError: Got unwanted exception (TypeError). 抛出错误
5. 判断值是否为真
  • assert.ifError(value)

如果value的值为真或者可以转换成true,则抛出value,否则断言通过。

assert.ifError(null);
// 通过。
assert.ifError(0);
// AssertionError [ERR_ASSERTION]: ifError got unwanted exception: 0
assert.ifError('错误');
// AssertionError [ERR_ASSERTION]: ifError got unwanted exception: '错误'
assert.ifError(new Error());
// AssertionError [ERR_ASSERTION]: ifError got unwanted exception: Error
6. 严格模式

当使用严格模式(strict mode)时,任何 assert 函数都将使用严格函数模式中使用的相等性。 因此,assert.deepEqual() 将与 assert.deepStrictEqual() 一样效果。

最重要的是,涉及对象的错误消息将产生错误的差异,而不是显示两个对象。 遗留模式则不是这种情况。

使用严格模式:

const assert = require('assert').strict;