核心外掛概念

外掛不僅僅是用於撰寫供應商整合。作為測試人員,您可以撰寫外掛來驗證輸入資料、對物件進行結構描述驗證,或確保 DOM 元素的正確行為。API 非常彈性,任何同步任務都可以輕鬆地封裝在單個斷言中,並在整個測試中重複使用。

本教學將向您展示如何存取 Chai 的外掛 API、使用旗標在語言鏈中傳輸資料,以及撰寫您的第一個斷言(以及詳盡的錯誤訊息)。完成此處後,建立 Helper 將向您展示如何組成屬性和方法,以在 Chai 語言鏈上使用。

存取工具

Chai 帶有一些工具來協助建構斷言,但它不會直接在 chai 匯出上提供這些工具。可以使用 chai 匯出的 use 方法來存取這些工具,該方法接受單個函數作為引數。

chai.use(function (_chai, utils) {
  // ...
});

將使用的函數會將兩個參數傳遞到其範圍。第一個是 chai 匯出,第二個是包含許多工具方法的物件(我們稍後會介紹)。

包含 chai 匯出,以便您可以建立可在多個測試檔案中使用的 Helper,或將您的 Helper 打包為外掛程式,以便與社群分享。以下是建立 Helper 的更合適模式…

對於我們的 Helper 檔案:test/helpers/model.js

module.exports = function (chai, utils) {
  var Assertion = chai.Assertion;

  // your helpers here
};

對於我們的實際測試:test/person.js

var chai = require('chai')
  , chaiModel = require('./helpers/model')
  , expect = chai.expect;

chai.use(chaiModel);

對於本文的其餘部分,我們將假設此結構…

  • 外部檔案中的 Helper
  • chai.Assertion 已指派給 Assertion 變數
  • 我們所有的 Helper 都會在匯出的函數內,位於指示的位置

Assertion 變數現在是斷言鏈的建構函式;new Assertion(obj) 現在等同於 expect(obj)

使用旗標

斷言在內部運作的最上層核心概念是旗標的概念。每個斷言都有一組大多是任意的旗標 - 鍵值對 - 與之關聯。Chai 在內部使用少數這些旗標,但開發人員也可以使用該儲存體來擴充。

旗標用法

旗標工具會在我們的 use 函數中公開為 utils.flag。它可以作為 getter 或 setter 使用,具體取決於傳遞給它的引數數量。

var myAssert = new Assertion(obj);
utils.flag(myAssert, 'owner', 'me'); // sets key `owner` to `me`
var owner = utils.flag(myAssert, 'owner'); // get key `owner', returns value

物件旗標

Chai 保留旗標中最重要的旗標是 object 旗標。這是斷言的主體。

var myAssert = new Assertion('Arthur Dent');
var obj = flag(myAssert, 'object'); // obj === 'Arthur Dent';

這個旗標經常使用,因此提供了一個快捷方式,即建構斷言的 _obj 屬性。

var obj = myAssert._obj; // obj === `Arthur Dent`

Chai 的核心斷言會使用以下旗標。如果您干擾這些旗標,可能會發生副作用。

  • object:(請參閱上方)
  • ssfi:開始堆疊函數 - 用於防止在錯誤中顯示回呼堆疊。
  • message:在使用 assert 介面時要包含在錯誤中的其他資訊。
  • negate:在鏈中包含 .not 時設定。
  • deep:在鏈中包含 .deep 時設定。由 equalproperty 使用
  • contains:當 includecontain 用作屬性時設定。變更 keys 的行為。
  • lengthOf:當 length 用作屬性時設定。變更 abovebelowwithin 的行為。

組成斷言

在開始將方法和屬性新增至語言鏈之前,我們應該先檢查如何調用斷言,以及如果斷言失敗的預期行為。

為此,每個建構的 Assertion 都有一個簡單名為 assert 的方法。它接受許多參數,並且它的行為可能會因斷言是否被否定而改變。

基本斷言

首先,我們將再次建構 Arthur,然後我們可以斷言他就是他所說的那個人。

var arthur = new Assertion('Arthur Dent');

arthur.assert(
    arthur._obj === 'Arthur Dent'
  , "expected #{this} to be 'Arthur Dent'"
  , "expected #{this} to not be 'Arthur Dent'"
);

Chai 會檢查第一個引數;如果它是 true,則斷言通過,但如果它是 false,則斷言失敗,並且第一個錯誤訊息將作為 chai.AssertionError 的一部分拋出。相反地,如果語言鏈被否定,它會認為 false 是通過,true 是失敗。第二個錯誤訊息將包含在拋出的錯誤中。

總而言之,assert 方法接受六個引數

  1. 布林值(真值測試的結果)
  2. 如果第一個引數為 false 時要使用的字串錯誤訊息
  3. 如果斷言被否定且第一個引數為 true 時要使用的字串錯誤訊息
  4. (選用)預期的值
  5. (選用)實際的值,預設為 _obj
  6. (選用)一個布林值,表示如果第一個引數為 false,除了訊息之外是否還要顯示差異

組成錯誤訊息

如您從以上範例所見,Chai 可以接受範本標籤來動態組成錯誤訊息。當使用時,這些範本標籤將被替換為相關物件的字串化表示。共有三個可用的範本標籤。

  • #{this}:斷言的 _obj
  • #{exp}:期望值,如果它在 assert 中提供
  • #{act}:實際值,預設為 _obj,但可以被 assert 中提供的值覆寫