Chai Change

Build Status

使用此 chai 斷言函式庫的外掛,斷言預期的變更已發生。此外掛可於 node 及瀏覽器中運作,且支援非同步或同步。

此外掛的概念是讓您的測試更加穩健。不要這樣做:

users.create();
expect(users.count()).to.equal(1);

而是斷言該動作實際導致了預期的變更

expect(() => {
  users.create();
}).to.alter(users.count, { by: 1 });

這樣做會更穩健,因為它避免了誤判:在此範例中,如果 users.count() 已是 1 且 users.create() 未實作,則第一個範例仍然會通過。使用變更預期,由於從起始值沒有 {by: 1} 的變更,因此測試會正確地失敗。

安裝

Node.js

chai-change 可於 npm 上取得。

  $ npm install chai-change

瀏覽器

可透過 npm 安裝,或下載 chai-change 並另存為 chai-change.js。然後只要在 chai.js 之後包含即可。

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

外掛

如果您在瀏覽器中使用 chai-change,則無需執行任何動作。

如果您使用 node,則只需要告知 chai 此外掛即可

const chai = require('chai');

chai.use(require('chai-change'));

Expect API

.change

斷言在函式執行後,傳遞至 change() 的函式所傳回的值發生變更

let x = 0;

expect(() => { x += 1; }).to.alter(() => x);
expect(() => {         }).not.to.alter(() => x);

您可以傳遞選項來指定預期的變更。使用 from 鍵來強制起始值、使用 to 鍵來強制結束值,以及使用 by 鍵來強制數值變更。

expect(() => { x += 1 }).to.alter(() => x, { by: 1 });
expect(() => { x += 1 }).to.alter(() => x, { from: x });
expect(() => { x += 1 }).to.alter(() => x, { from: x, to: x + 1 });
expect(() => { x += 1 }).to.alter(() => x, { to: x + 1 });

Assert API

assert.alters

斷言在執行 changer 函式後,changeWatcher 所傳回的值發生變更

let x = 0;
assert.alters(changer, changeWatcher);

function changer() { x += 1; }
function changeWatcher() { return x }

您可以傳遞選項來指定預期的變更。使用 from 鍵來強制起始值、使用 to 鍵來強制結束值,以及使用 by 鍵來強制數值變更。

assert.alters(() => { x += 1 }, () => x, { by: 1 });
assert.alters(() => { x += 1 }, () => x, { from: x });
assert.alters(() => { x += 1 }, () => x, { from: x, to: x + 1 });
assert.alters(() => { x += 1 }, () => x, { to: x + 1 });

assert.unaltered

斷言在執行 changer 後,changeWatcher 所傳回的值未變更

let x = 0;
const noop = () => undefined;
assert.unaltered(noop, () => x);

非同步斷言

changerchangeWatcher 回呼皆可傳回 promise,或採用 node 風格的回呼,並以 error 作為第一個參數。如果您提供回呼,則需要為變更斷言提供最終的 callback: 選項,該選項用於通知您的測試執行器測試已完成。

使用 promise

許多測試執行器(例如 mocha)都支援從 it()test() 區塊中直接傳回 promise 來支援非同步測試。 chai-change 支援此樣式。

如果您的執行器不支援傳回 promise,您可以使用 .then() 方法來呼叫基於回呼的 API 等(或使用 callback:,如以下錯誤優先回呼文件所述)。


it("creates a user", () => {
  let count = 0;
  const User = {
    create(attrs) {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          count += 1
          resolve();
        });
      });
    },
    count() {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve(count);
        });
      });
    },
  };

  // when `changer` or `changeWatcher` returns a promise the expectation will return a promise as well
  return expect(() => (
    User.create({name: "bob"});
  )).to.alter(() => (
    User.count();
  ),{
    by: 1,
  });
})

使用錯誤優先回呼

let count = 0;
const User = {
  create(attrs,cb) {
    setTimeout(() => {
      count += 1
      cb();
    });
  },
  count(cb) {
    setTimeout(() => {
      cb(null,count);
    });
  },
};

expect((stepDone) => {
  User.create({name: "bob"}, stepDone)
}).to.alter((stepDone) => {
  User.count(stepDone);
},{
  by: 1,
  callback: done
});

測試

Node:npm install && npm test

瀏覽器:npm install 然後開啟 test/index.html

變更日誌

### 2.1

Promise 支援 - 感謝 @talyssonoc

changeWatcherchanger 函式現在皆可傳回 promise。與 promise 一起使用時,預期也會傳回 promise,可直接與 mocha 等一起使用。

2.0

  • 重大變更 將整個 API 從 change 變更為 alter,以避免 .change 方法在 chai@2.0.0 中新增至 chai。