Chai Change
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);
非同期アサート
changer と changeWatcher コールバックはどちらも、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に変更しました。