溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

assert斷言如何在node.jsz中使用

發(fā)布時間:2021-03-30 16:24:14 來源:億速云 閱讀:105 作者:Leah 欄目:web開發(fā)

這期內(nèi)容當中小編將會給大家?guī)碛嘘P(guān)assert斷言如何在node.jsz中使用,文章內(nèi)容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

一. 簡介

斷言是編程術(shù)語,表示為一些布爾表達式,程序員相信在程序中的某個特定點該表達式值為真,可以在任何時候啟用和禁用斷言驗證,因此可以在測試時啟用斷言而在部署時禁用斷言。同樣,程序投入運行后,最終用戶在遇到問題時可以重新啟用斷言。

使用斷言可以創(chuàng)建更穩(wěn)定、品質(zhì)更好且 不易于出錯的代碼。當需要在一個值為FALSE時中斷當前操作的話,可以使用斷言?!締卧獪y試】必須使用斷言。

Node提供了 10 多個斷言測試的函數(shù),用于測試不變式,我在文章中中將這 10 多個函數(shù)進行了分組,方便理解記憶。

【提示】在本文章中,expected 代表預期值,actual 代表實際值, message 代表自定義信息

二. 判斷值是否為真值

判斷值是否為真值有以下兩個斷言測試函數(shù)

2.1 assert(value[, message])

這個測試函數(shù)在 【Boolean(value)】 為 【true】時通過斷言測試,否則拋出 【AssertionError】

const assert = require("assert");

assert("blue","第一個值為false時以我為錯誤信息拋出");

assert(true,"第一個值為false時以我為錯誤信息拋出");

上面一段代碼由于【Boolean(value)】全部為 true,所以全部通過斷言測試

assert(false,"第一個值為false時以我為錯誤信息拋出");

// AssertionError [ERR_ASSERTION]: 第一個值為false時以我為錯誤信息拋出

上面代碼中 value 為false,則拋出一個帶有 message 屬性的 【AssertionError】,其中 message 屬性的值等于傳入的 message 參數(shù)的值。 【如果 message 參數(shù)為 undefined,則賦予默認的錯誤信息】。

assert(false);
// AssertionError [ERR_ASSERTION]: false == true

上面代碼由于沒有指定【message】參數(shù),拋出的為默認錯誤信息的【AssertionError】

2.2 assert.ok(value[, message])

assert.ok() assert()的作用是一樣的,都是測試【value】是否為真值。而且用法也一樣,所以可以將assert()視為assert.ok()的語法糖

const assert = require("assert");
assert.ok(true);
assert.ok(1);

上面代碼【Boolean(value)】全部為 true,所以全部斷言通過,下面是斷言不通過的情況,分別列出了默認錯誤信息

assert.ok(0);
//AssertionError [ERR_ASSERTION]: 0 == true

assert.ok(false);
//AssertionError [ERR_ASSERTION]: false == true

assert.ok(false,"自定義錯誤信息");
//AssertionError [ERR_ASSERTION]: 自定義錯誤信息

三. 判斷預期值和實際值相等(==)

這一組里面有兩個測試函數(shù),用于測試預期值與實際值是否相等,如果相等則斷言通過,否則拋出 【AssertionError】

3.1 assert.equal(actual, expected[, message])

assert.equal()用于測試期望值和實際值是否相等,【在值類型的時候比較的是兩個值是否相等,當預期值和實際值為引用類型的時候,比較的是值得引用】

assert.equal(1, 1);
assert.equal("1", 1);

上面代碼是對值類型進行的比較,說明equal()在內(nèi)部使用的是(==),而非嚴格相等,待會兒我會總結(jié)到嚴格相等(===)

assert.equal({},{},"AssertionError");
assert.equal(() => { }, () => { }, "AssertionError");
assert.equal([],[],'AssertionError');

上面三個表達式都會拋出【message】屬性值為'AssertionError'的【AssertionError】對象,【所以當值為引用類型的時候,equal()比較的是值得引用,因此兩個引用類型的值是沒法通過equal()斷言的】

const obj={};
assert.equal(obj,obj);
// 斷言通過

上面代碼由于比較的是同一個對象,兩個值得引用相等,所以斷言通過。

3.2 assert.deepEqual(actual, expected[, message])

同樣也是測試 預期值 和 實際值 是否相等,使用的仍然是(==),但是與equal不同的是,【deepEqual()在對引用類型進行比較的時候,不是對值的引用進行比較,而是比較的對象的屬性值】

const a = 'Blue', b = 'Pink';
assert.deepEqual(a,a,'actual unequal to expected');
// 斷言通過
assert.deepEqual(a,b,'actual unequal to expected');
// AssertionError [ERR_ASSERTION]: actual unequal to expected

上面是對值類型進行的比較,和equal()沒有任何的區(qū)別

const obj1 = { name: "foo", gender: "men" },
 obj2 = { name: "foo", gender: "men" },
 obj3 = { name: "bar", gender: "men" }
assert.deepEqual(obj1, obj2, 'actual unequal to expected');
// 斷言通過
assert.deepEqual(obj1, obj3, 'actual unequal to expected');
// AssertionError [ERR_ASSERTION]: actual unequal to expected

上面代碼是對引用類型的比較,可以看出【deepEqual() 】比較的是屬性值,而非引用,這是與equal()不同的地方。

【注意??!】deepEqual()只測試可枚舉的自身屬性,不測試對象的原型、連接符、或不可枚舉的屬性(這些情況使用 assert.deepStrictEqual() ,稍后會總結(jié)到)

const son1 = Object.create(obj1),
 son2 = Object.create(obj2);

son1.name="Summer";
son2.name="Summer";

assert.deepEqual(son1,son2,"actual unequal to expected");
// 斷言通過

上面代碼中 son1 和 son2 分別繼承與兩個不同的對象,都擁有 name 為 “Summer” 的屬性,最后的的結(jié)果是通過,說明【deepEqual()不測試對象的原型】

const ena = {}, enb = {};
Object.defineProperties(ena,{
 name:{
 value:"Blue"
 },
 hobby:{
 value:"foo",
 enumerable:false //可枚舉性設(shè)置為false
 }
});
Object.defineProperties(enb,{
 name:{
 value:"Blue"
 },
 hobby:{
 value:"bar",
 enumerable:false //可枚舉性設(shè)置為false
 }
})
assert.deepEqual(ena,enb,"actual unequal to expected") 
//ok,actual equal to expected

上面代碼中 ena 和 enb 用于相同的可枚舉屬性【name】,有著值不同的不可枚舉屬性【hobby】,說明【deepEqual()不測試對象的不可枚舉的屬性】

四. 判斷預期值和實際值全等(===)

這組測試函數(shù)是用于判斷預期值和實際值是否深度相等的,內(nèi)部使用的是(===),所以對象的原型也會進行比較,值得類型也是比較的范圍。這組也有兩個測試函數(shù)。

4.1 assert.deepStrictEqual(actual, expected[, message])

由于內(nèi)部使用的是全等(===),所以對象的原型也會計入比較的范圍

const obj1 = { name: "foo", gender: "men" },
 obj2 = { name: "bar", gender: "men" }
const son1 = Object.create(obj1),
 son2 = Object.create(obj2);
son1.name = "Summer";
son2.name = "Summer";
assert.deepEqual(son1, son2, "actual unequal to expected");
//斷言通過
assert.deepStrictEqual(son1, son2, "actual unequal to expected")
//AssertionError [ERR_ASSERTION]: actual unequal to expected

上面代碼使用了deepEqual()deepStrictEqual()進行了斷言測試,son1 和 son2 分別繼承與兩個不同的對象,但是擁有相同的屬性值??梢钥闯觥?code>deepEqual()是不會考慮對象的原型的,deepStrictEqual()將原型對象列入了比較對象】

4.2 assert.strictEqual(actual, expected[, message])

strictEqual()equal()的加強,考慮了數(shù)據(jù)類型;如果actual === expected,則斷言通過,否則拋出AssertionError,message?message:默認錯誤信息。

assert.strictEqual(1, 2);
// 拋出 AssertionError: 1 === 2

assert.strictEqual(1, 1);
// 測試通過。

assert.strictEqual(1, '1');
// 拋出 AssertionError: 1 === '1'

assert.equal(1, '1');
// 測試通過。

【提示!!】對引用類型還是永遠通不過【strictEqual()】斷言測試

五. 判斷預期值和實際值不相等(!=)

上面總結(jié)到了判斷預期值和實際值相等,這兒總結(jié)一下判斷預期值和實際值不想等的兩個測試函數(shù),實際上就是上面 (三) 的逆運算。

5.1 assert.notEqual(actual, expected[, message])

notEqual()】為 【equal() 】的逆運算,如果 actual!= expected 則斷言通過,同樣對于值類型是單純對值進行比較,對應(yīng)引用類型比較的是值得引用

assert.notEqual("1", "2");
// 斷言通過

assert.notEqual("1", 2);
// 斷言通過

assert.notEqual("1", 1);
// AssertionError [ERR_ASSERTION]: '1' != 1

上面代碼是對值類型進行的比較,第三個表達式的默認信息可以看出內(nèi)部使用的是(!=)

assert.notEqual({ a: "foo" }, { a: "foo" });

assert.notEqual(() => { }, () => { });

assert.notEqual([], []);

上面的代碼是對引用類型進行的斷言測試,【notEqual() 】對于兩個對象的測試通過是一個【恒成立】的結(jié)果。

5.2 assert.notDeepEqual(actual, expected[, message])

notDeepEqual() 】為 【deepEqual() 】的逆運算,如果 actual!= expected 則斷言通過,不同于notEqual()的是對于引用類型是對值進行判斷,不比對原型、不可枚舉屬性,只比對自有可枚舉屬性,斷言通過。

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');
// 斷言通過

上面代碼中最后一個表達式斷言通過,說明【不比對原型、不可枚舉屬性,只比對自有可枚舉屬性】

【注意??!】與notEqual的區(qū)別,也就是deepEqual和equal的區(qū)別,在引用數(shù)據(jù)類型的時候,deepEqual是比較的值而非引用,equal對比的是引用,所以引用類型在equal的時候是永遠無法通過斷言測試的,以此類推,引用類型在notEqual時是永遠否可以通過斷言測試的。

六. 判斷預期值和實際值嚴格不相等(!==)

上面總結(jié)到了判斷預期值和實際值嚴格相等,這兒總結(jié)一下判斷預期值和實際值嚴格不相等的兩個測試函數(shù),實際上就是上面 (四) 的逆運算

6.1 assert.notStrictEqual(actual, expected[, message])

如果actual與expected不 !== 則斷言通過, 與 assert.deepStrictEqual() 相反

assert.notStrictEqual("1", 1);
// 斷言通過

assert.notStrictEqual("1", "1");
// AssertionError [ERR_ASSERTION]: '1' !== '1'

上面代碼是對值類型進行的斷言測試,可以看出【notStrictEqual() 】考慮了數(shù)據(jù)類型

assert.notStrictEqual({ a: "foo" }, { a: "foo" });
assert.notStrictEqual(() => { }, () => { });
assert.notStrictEqual([], []);

上面代碼是對引用類型的測試,全部通過,以上表達式是恒通過的。

6.2 assert.notDeepStrictEqual(actual, expected[, message])

notDeepStrictEqual()就是deepStrictEqual()的逆運算,如果 actual !== expected 則斷言通過,否則拋出AssertionError。

assert.notDeepStrictEqual({ a: '1' }, { a: 1 });
//斷言通過

assert.notDeepStrictEqual({ a: '1' }, { a: "1" });
//AssertionError [ERR_ASSERTION]: { a: '1' } notDeepStrictEqual { a: '1' }

七. 斷言錯誤并拋出

這一組有 四 個(可以說是 三 個)測試函數(shù),是對錯誤進行的處理。

7.1 assert.fail(message)

這個測試函數(shù)不多說,可以看錯是下一個函數(shù)的重載,用于主動拋出帶有【message】屬性的【AssertionError】對象

assert.fail("自定義錯誤信息");
// AssertionError [ERR_ASSERTION]: 自定義錯誤信息

7.2 assert.fail(actual, expected[, message[, operator[, stackStartFunction]]])

該測試函數(shù)用于主動拋出自定義錯誤信息,拋出錯誤信息格式:【actual 參數(shù) + operator 參數(shù) + expected 參數(shù)】

assert.fail("BLUE","PINK");  
// AssertionError [ERR_ASSERTION]: 'BLUE' != 'PINK'

上面代碼不提供【message】和【operator】,則【operator】默認為 【!=】

assert.fail("BLUE","PINK","自定義的錯誤信息");  
// AssertionError [ERR_ASSERTION]: 自定義的錯誤信息

assert.fail("BLUE","PINK","自定義的錯誤信息","?",()=>{
  console.log("hello");
 });
// AssertionError [ERR_ASSERTION]: 自定義的錯誤信息

上面代碼提供【message】,這時候 【actual】、【operator】、【expected】等參數(shù)會被列入錯誤對象屬性中

assert.fail("BLUE","PINK",undefined);
// AssertionError [ERR_ASSERTION]: 'BLUE' undefined 'PINK'

assert.fail("BLUE","PINK",undefined,"?");
// AssertionError [ERR_ASSERTION]: 'BLUE' ? 'PINK'

上面代碼是【message】為 undefined 時,會檢測【operator】參數(shù),【operator?operator:undefined

7.3 assert.throws(block,error, message)

參數(shù)說明:

block | Function

error | RegExp | Function

message | any

【說明!!】如果block拋出的錯誤滿足error參數(shù),也就是拋出錯誤與期望一致,則斷言通過,否則拋出block中的錯誤,如果block不拋出錯誤,則拋出【AssertionError 】。

【提示??!】error 參數(shù)可以是構(gòu)造函數(shù)、正則表達式、或自定義函數(shù)。

assert.throws(
 () => {
  throw new Error('錯誤信息');
 },
 Error
);

上面代碼中 error 參數(shù)為構(gòu)造函數(shù),【block】拋出的錯誤與預期的一致,所以斷言通過。

assert.throws(
 () => {
  throw new Error('錯誤信息');
 },
 /錯誤/
);

上面代碼中 error 參數(shù)為正則表達式,【block】拋出的錯誤滿足正則表達式,所以斷言通過。

【注意??!】error 參數(shù)不能是字符串。 如果第二個參數(shù)是字符串,則視為省略 error 參數(shù),傳入的字符串會被用于 【message】 參數(shù),

// 這是錯誤的!不要這么做!
assert.throws(myFunction, '錯誤信息', '沒有拋出期望的信息');

// 應(yīng)該這么做。
assert.throws(myFunction, /錯誤信息/, '沒有拋出期望的信息');

下面代碼,【error】 參數(shù)為自定義函數(shù)

assert.throws(
 () => {
  throw new Error('錯誤信息');
 },
 function (err) {
  if ((err instanceof Error) && /錯誤/.test(err)) {
   return true;
  }
 },
 '不是期望的錯誤'
);

7.4 assert.doesNotThrow(block, error, message)

【說明??!】預期的錯誤和實際的錯誤一致時,不拋出實際錯誤,拋出AssertionError,不一致則拋出實際錯誤信息

assert.doesNotThrow(
 () => {
 throw new TypeError('錯誤信息');
 },
 SyntaxError
);

以上例子會拋出 TypeError,因為在斷言中沒有匹配的錯誤類型

assert.doesNotThrow(
 () => {
 throw new TypeError('錯誤信息');
 },
 TypeError
);

以上例子會拋出一個帶有 Got unwanted exception (TypeError).. 信息的 AssertionError

assert.doesNotThrow(
 () => {
 throw new TypeError('錯誤信息');
 },
 TypeError,
 '拋出錯誤'
);
// 拋出 AssertionError: Got unwanted exception (TypeError). 拋出錯誤

上面代碼說明:如果拋出了 AssertionError 且有給 message 參數(shù)傳值,則 message 參數(shù)的值會被附加到 AssertionError 的信息中

八. 判斷值是否為真

這兒只有一個測試函數(shù)了

8.1 assert.ifError(value)

如果value的值為真或者可以轉(zhuǎn)換成true,則拋出value,否則斷言通過。

assert.ifError(true); 
//拋出true

assert.ifError(false);
//斷言通過

上面代碼中是直接給出的 布爾 類型的值,如果值為 true 則會將該值拋出,否則什么也不做

assert.ifError(0);
//斷言通過

assert.ifError("0");
//拋出 "0"

assert.ifError(1);
//拋出 1

assert.ifError(new Error());
//拋出 Error,對象名稱

上述就是小編為大家分享的assert斷言如何在node.jsz中使用了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關(guān)知識,歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI