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

changeWatcher によって返される値が、changer 関数の実行後に変更されることをアサートします

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

changeWatcher によって返される値が、changer 関数の実行後も変更されないことをアサートします

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

非同期アサート

changerchangeWatcher コールバックはどちらも、promiseを返すか、最初の引数として error を持つnodeスタイルのコールバックを取ることができます。コールバックを提供する場合は、テストが完了したことをテストランナーに通知するために使用される、最終的な callback: オプションをchangeアサーションに指定する必要があります。

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のおかげです!

changeWatcher 関数と changer 関数の両方がpromiseを返すことができるようになりました。また、期待値はpromiseと併用するとpromiseを返し、mochaなどと直接使用できます。

2.0

  • 破壊的変更 chai@2.0.0 でchaiに追加された .change メソッドとの衝突を避けるため、API全体を change から alter に変更しました。