dirty-chai
用於終止斷言屬性的函式形式。
安裝
npm install dirty-chai --save-dev
用法
dirty-chai
是一個 chai 的 外掛。
var chai = require('chai');
var dirtyChai = require('dirty-chai');
var expect = chai.expect
chai.use(dirtyChai);
// ...
expect(true).to.be.true();
自訂錯誤訊息
使用此函式形式來終止屬性時,您也可以提供自訂的錯誤訊息,在斷言失敗時顯示。無論斷言是在鏈的哪個位置(中間或結尾)都有效。
expect(true).to.be.true.and.not.false('Reason: Paradox');
expect(true).to.be.true('The fabric of logic has torn').and.not.false();
受影響的斷言
以下內建的斷言會被此外掛修改為使用函式呼叫的形式
- ok
- true
- false
- null
- undefined
- exist
- empty
- arguments
- 引數
注意事項
永遠以函式終止
這些形式可以混合使用,但鏈必須永遠以函式形式終止,否則鏈中直到該點的斷言都不會執行。
expect(true).to.be.true.and.not.false();
expect(true).to.be.true().and.not.false();
鏈的長度/引數
當 length
和 arguments
斷言在鏈中跟在其他斷言之後時,此作法會破壞它們。為了解決這個限制,請將 length
或 arguments
斷言放在鏈中的最前面,或者直接使用多個斷言語句。
myArray.should.exist.and.should.have.length(3); // Error: length is not a function
// Do two assert statements instead
myArray.should.exist();
myArray.should.have.length(3);
** 與 chai-as-promised 一起使用 **
如果您正在使用 chai-as-promised,您應該在 dirty-chai 之前 .use
chai-as-promised
var chai = require("chai");
var chaiAsPromised = require("chai-as-promised");
var dirtyChai = require("dirty-chai");
chai.use(chaiAsPromised);
chai.use(dirtyChai);
外掛斷言
此外掛也會掛鉤並轉換其他 Chai 外掛所加入的任何屬性斷言。您唯一需要做的是確保在載入其他外掛之前載入 dirty-chai,以便它可以在載入其他外掛之前將其掛鉤到位。
例如,如果您在 dirty-chai 之後載入 sinon-chai,它的所有屬性斷言現在都將變成方法斷言。
spy.should.have.been.called();
spy.should.have.been.calledOnce();
spy.should.have.been.calledTwice();
為什麼?
Chai 可能是 node 中最受歡迎的斷言函式庫之一。它有超過 400 個依賴項,每月下載量將近 500,000 次。
由於風格上的原因,Chai 的設計方式是讓任何不需要參數的斷言都只會在屬性存取時進行斷言。這使得這些斷言可以省略如果這些斷言是方法時所需要的空括號。
這個設計決策對於您可以對測試的信任度產生相當大的影響,特別是當您沒有嚴格遵守 TDD 的紅-綠-重構流程時。如需深入了解原因,請閱讀小心在屬性存取時斷言的函式庫。
還有一個問題是會收到來自 JSHint 等 linter 的錯誤。如果您正在檢查測試程式碼,您的 linter 會抱怨一個類似「預期一個賦值或函式呼叫,但卻看到一個表達式」的錯誤。由於 linter 不知道屬性 getter,它會假設這一行沒有副作用,並發出警告,以防您犯了錯誤。
抑制這些錯誤不是一個好方法,因為測試程式碼的重要性正變得與生產程式碼一樣,甚至更高。使用靜態分析來捕捉測試中的語法錯誤是一個很好的工具,可以幫助確保您的測試定義明確且沒有錯字。
撰寫此外掛是為了讓我們仍然可以利用使用/為 Chai 撰寫的大型專案和外掛生態系統,同時仍然能夠信任您的測試。它將內建的屬性斷言轉換為方法斷言,包括外掛所加入的任何屬性斷言。
受影響的斷言清單,以及外掛加入的許多斷言,都是在存取時立即斷言的屬性 getter。因此,它們的設計目的是透過屬性存取來終止斷言鏈。
expect(true).to.be.true;
foo.should.be.ok;
一個更好的選擇是為這些斷言提供一個函式呼叫的形式,這樣程式碼的意圖會更清楚,而且 linter 不再抱怨看起來不對勁的地方。此形式是除了現有的屬性存取形式之外加入的,並且不會影響現有的測試程式碼。
expect(true).to.be.true();
foo.should.be.ok();