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;
複製程式碼