Chai Spies

這是 chai 斷言庫的一個附加外掛。它提供最基本的功能間諜(spy)能力和測試。

這個庫主要目的是作為有興趣開發 chai 外掛的任何人的起點。如果您正在開發一個模組,歡迎使用它作為起點。我也鼓勵使用編譯工具,使模組能夠在 node.js 和瀏覽器中運作。

安裝

Node.js

Chai spies 在 npm 上可用。

  $ npm install chai-spies

瀏覽器

在包含 chai.js 之後,包含 chai-spies.js

<script src="chai-spies.js"></script>

外掛程式

如果您在瀏覽器中使用 chai-spies,則無需執行任何操作。它將檢測全域命名空間中的 chai 並自動使用。

如果您正在使用 node,這是一個有用的片段。

const chai = require('chai')
  , spies = require('chai-spies');

chai.use(spies);

const should = chai.should()
  , expect = chai.expect;

TypeScript 設定

如果使用 TypeScript,這是在使用的方式 chai-spies

import { expect } from 'chai';
import spies from 'chai-spies';
chai.use(spies);

為瀏覽器構建

目前,此套件使用 rollup 來捆綁原始程式碼。只需使用 npm run build 來構建瀏覽器版本。

Chai Spies API 參考

建立間諜(Spies)

在此模組中,間諜可以是空函數,或是一個包裝的具名函數。一旦 chai 被擴充,您就可以透過 chai 自己的介面建立間諜。

function original () {
  // do something cool
}

const spy = chai.spy(original);

// then use in place of original
ee.on('some event', spy);

// or use without original
const spyAgain = chai.spy();
ee.on('some other event', spyAgain);

spy.on

spy.on 允許在物件的現有方法上新增間諜。

const array = [1, 2, 3];

chai.spy.on(array, 'push');

// or multiple spies
chai.spy.on(array, ['push', 'pop']);

也可以提供被間諜方法自訂的實作。

chai.spy.on(array, 'push', function (...items) {
  // custom implementation of `push` method
});

使用箭頭函式,也可以輕鬆地用常數取代方法實作。

chai.spy.on(array, 'push', () => 5);

// or more readable :)
chai.spy.on(array, 'push', returns => 5);

spy.interface

此方法會建立一個模擬(或間諜物件):一個介面,該介面的每個方法上都有間諜。物件的方法可以有虛假的實作或沒有實作。

// with no implementation
const arrayLike = chai.spy.interface('arrayLike', ['push', 'pop', 'filter']);

// with fake implementation
const arrayLike = chai.spy.interface({
  push(item) {
    this.__items = this.__items || [];
    return this.__items.push(item)
  },
  // other method implementations
});

arrayLike.push(5);

spy.returns(已棄用)

chai.spy.returns 只是一個簡單的 helper,它會建立一個回傳常數的函式。

const returnTrue = chai.spy.returns(true);

returnTrue(); // true

最好使用箭頭函式。

const returnTrue = chai.spy(returns => true);

沙箱(Sandboxes)

沙箱是一組間諜。沙箱允許追蹤物件上的方法,並透過 restore 呼叫來還原原始方法。若要建立沙箱:

const sandbox = chai.spy.sandbox();

describe('Array', () => {
  let array;

  beforeEach(() => {
    array = [];
    sandbox.on(array, ['push', 'pop']);
  });

  afterEach(() => {
    sandbox.restore(); // restores original methods on `array`
  })

  it('allows to add items', () => {
    array.push(1);

    expect(array.push).to.have.been.called.with(1);
  });
});

chai.spy.onchai.spy.restore 會繫結到預設沙箱。因此,若要還原所有由 chai.spy.on 間諜的方法,只需呼叫 chai.spy.restore()(不帶引數)。

restore 方法接受 2 個選用引數:要還原的物件和要還原的方法或多個方法。因此,此呼叫也有效:

const array = [1, 2, 3];

chai.spy.on(array, ['push', 'pop']);

chai.spy.restore(array) // restores all methods on object
chai.spy.restore(array, 'push') // restores only `push` method

斷言

.spy

斷言物件是間諜。

expect(spy).to.be.spy;
spy.should.be.spy;

.called

斷言已呼叫間諜。否定通過。

expect(spy).to.have.been.called();
spy.should.have.been.called();

請注意,called 可以用作可鏈結的方法。

.with

斷言至少呼叫過一次間諜,且使用了給定的引數,即使提供了更多引數。

spy('foo');
expect(spy).to.have.been.called.with('foo');
spy.should.have.been.called.with('foo');

也會通過 spy('foo', 'bar')spy(); spy('foo')

如果與多個引數一起使用,則斷言至少呼叫過一次間諜,且使用了所有給定的引數。

spy('foo', 'bar', 1);
expect(spy).to.have.been.called.with('bar', 'foo');
spy.should.have.been.called.with('bar', 'foo');

.with.exactly

類似於 .with,但只有在引數清單與提供的引數完全相同時才會通過。

spy();
spy('foo', 'bar');
expect(spy).to.have.been.called.with.exactly('foo', 'bar');
spy.should.have.been.called.with.exactly('foo', 'bar');

不會通過 spy('foo')spy('bar')spy('bar'); spy('foo')spy('foo'); spy('bar')spy('bar', 'foo')spy('foo', 'bar', 1)

也可以用於僅帶單一引數的呼叫。

.always.with

斷言每次呼叫間諜時,引數清單都包含給定的引數。

spy('foo');
spy('foo', 'bar');
spy(1, 2, 'foo');
expect(spy).to.have.been.called.always.with('foo');
spy.should.have.been.called.always.with('foo');

.always.with.exactly

斷言間諜從未使用與提供的引數清單不同的引數清單呼叫。

spy('foo');
spy('foo');
expect(spy).to.have.been.called.always.with.exactly('foo');
spy.should.have.been.called.always.with.exactly('foo');

.nth(n).called.with

斷言已使用提供的引數清單呼叫間諜的第 n 次呼叫。此斷言帶有其他三個變體:

  • .first.called.with
  • .second.called.with
  • .third.called.with
spy('foo');
spy('bar');
spy('baz');
spy('foobar');
expect(spy).to.have.been.first.called.with('foo');
spy.should.have.been.first.called.with('foo');
expect(spy).on.nth(5).be.called.with('foobar');
spy.should.on.nth(5).be.called.with('foobar');

這些斷言要求間諜至少被呼叫了所需次數,例如:

spy('foo');
spy('bar');
expect(spy).to.have.been.third.called.with('baz');
spy.should.have.been.third.called.with('baz');

不會通過,因為間諜尚未被呼叫第三次。

.once

斷言已精確呼叫一次間諜。

expect(spy).to.have.been.called.once;
expect(spy).to.not.have.been.called.once;
spy.should.have.been.called.once;
spy.should.not.have.been.called.once;

.twice

斷言已精確呼叫兩次間諜。

expect(spy).to.have.been.called.twice;
expect(spy).to.not.have.been.called.twice;
spy.should.have.been.called.twice;
spy.should.not.have.been.called.twice;

.exactly(n)

斷言已精確呼叫 n 次間諜。

expect(spy).to.have.been.called.exactly(3);
expect(spy).to.not.have.been.called.exactly(3);
spy.should.have.been.called.exactly(3);
spy.should.not.have.been.called.exactly(3);

.min(n) / .at.least(n)

斷言已呼叫間諜至少 n 次。

expect(spy).to.have.been.called.min(3);
expect(spy).to.not.have.been.called.at.least(3);
spy.should.have.been.called.at.least(3);
spy.should.not.have.been.called.min(3);

.max(n) / .at.most(n)

斷言已呼叫間諜最多 n 次。

expect(spy).to.have.been.called.max(3);
expect(spy).to.not.have.been.called.at.most(3);
spy.should.have.been.called.at.most(3);
spy.should.not.have.been.called.max(3);

.above(n) / .gt(n)

斷言已呼叫間諜超過 n 次。

expect(spy).to.have.been.called.above(3);
expect(spy).to.not.have.been.called.gt(3);
spy.should.have.been.called.gt(3);
spy.should.not.have.been.called.above(3);

.below(n) / .lt(n)

斷言已呼叫間諜少於 n 次。

expect(spy).to.have.been.called.below(3);
expect(spy).to.not.have.been.called.lt(3);
spy.should.have.been.called.lt(3);
spy.should.not.have.been.called.below(3);

測試

測試是使用 mocha 在 BDD 介面中撰寫的。可以使用 npm test 執行 Node 測試。可以透過開啟 test/browser/index.html 來檢視瀏覽器測試。

貢獻者

專案:chai-spies
儲存庫存在時間:3 年 2 個月
活躍時間:26 天
提交次數:77
檔案:12
作者
48 Jake Luer 62.3%
7 Glenn Jorde 9.1%
4 Keith Cirkel 5.2%
3 = 3.9%
3 Sergiy Stotskiy 3.9%
2 JamesMaroney 2.6%
2 PG Herveou 2.6%
2 Ryckes 2.6%
1 Veselin Todorov 1.3%
1 Steffen 1.3%
1 Daniel Walker 1.3%
1 Domenic Denicola 1.3%
1 Andre Jaenisch 1.3%
1 PG 1.3%

授權

(MIT 授權)

版權所有 (c) 2012 Jake Luer jake@alogicalparadox.com

特此授權,免費授予任何取得本軟體及相關文件檔(「軟體」)副本之人,在不受限制的情況下處理本軟體,包括但不限於使用、複製、修改、合併、發布、散佈、再授權及/或銷售本軟體副本的權利,並允許向取得本軟體之人授與上述權利,但需符合下列條件:

上述版權聲明及本授權聲明應包含在本軟體的所有副本或主要部分中。

本軟體以「現狀」提供,不提供任何明示或暗示的擔保,包括但不限於對適銷性、特定用途的適用性及未侵權的擔保。作者或版權持有人在任何情況下均不對因軟體或軟體的使用或其他處理方式而產生或與其相關的任何索賠、損害或其他責任負責,無論是依據契約、侵權或其他方式提出的訴訟。