node.jsのソースを単体テストするmocha+chaiの使い方
node.jsのソースを単体テストするmocha+chaiの使い方についてです。
ここでは、mocha4.0.0、chai4.1.2を使用しています。
まずchaiをrequireして、assertというchaiのAPIを使用します。
const chai = require('chai');
const assert = chai.assert;
次にテストしたいコードを書きます。
const chai = require('chai');
const assert = chai.assert;
const myFunc = function(a, b){
return a+b;
};
テストは、mochaが用意してくれているdescribeメソッドを使用します。
以下、簡単な記述例です。
const chai = require('chai');
const assert = chai.assert;
const myFunc = function(a, b){
return a + b;
};
describe('テストのタイトル', function () {
it('myFuncのテスト', function() {
assert.strictEqual(myFunc(1, 2), 3);
});
});
describeの第一引数は、テストタイトルです。第二引数がcallback関数となっており、その中に、itメソッドを記述します。このitメソッド単位にテストを実行します。
その為、describeの中にはitメソッドはいくつでも記述することができます。
assert.strictEqualメソッドの第一引数と第二引数を比較します。
上記のファイルを「index.test.js」として保存します。
コマンドプロンプトから以下のように実行します。
C:\>mocha index.test.js // グローバルインストールの場合
結果は以下のようにOKなら緑色になります。NGなら赤色になります。
describe.skip
describe.skip~とすることで、その中のitテストは全てスキップされます。
xdescribeと書いても同じです。
itだけをスキップしたいときは、it.skipもしくはxitと書きます。
describe.only
describe.only~とすることで、その中のitテストだけをテストすることができます。
it.only~とすることもできます。
これはよく使いますが、最後はonlyを削除するのを忘れないように注意してください。
describeの入れ子
describeの中にdescribeを書くことができます。
describe('タイトル', () => {
describe('タイトル', () => {
// ここにitを書く
});
});</pre.
beforeEach
mochaにはbeforeEachと言うメソッドが用意されています。 beforeEachはdescribeの中、かつ、itの上に書きます。 各itテストの前でbeforeEachが実行されます。使い方の例としては、テストデータをインサートしたりとかでしょうか。 以下、記述例です。
beforeEach(function(done) {
// ここに書く
done();
});
afterEach
これはbeforeEachとは逆に、各itの終わりに実行されます。
エラー
ResourceInUseException: Table already exists: テーブル名
…そのテーブルが既に存在する場合にcreateTableすると発生する。
Promiseオブジェクトを比較する方法
Promiseオブジェクトをアサーションするのは少し難しいです。
が、chai-as-promisedモジュールを使えば簡単に比較することができるようになります。
インストールは以下のとおりです。
npm install chai-as-promised --save-dev
7.1.1をインストールしました。まず、chai-as-promisedを使わずに、以下のようなテストを実行してみます。
it('Promiseのテスト', function(){
let p1 = Promise.resolve(123);
expect(p1).to.deep.equal(123);
});
結果は以下のようにエラーとなります。
AssertionError: expected {} to deeply equal 123
次にchai-as-promisedを使ってみます。
chai.useを使用します。
const chai = require('chai');
const cap = require('chai-as-promised');
const expect = chai.expect;
chai.use(cap);// これが必要
describe('Promiseテスト', function () {
it('Promiseのテスト1', function(){
let p1 = Promise.resolve(123);
expect(p1).to.deep.eventually.equal(123);
});
});
expectの引数にPromiseオブジェクトを指定し、to.deep.equalではなく、to.deep.eventually.equalを使用します。
引数にはプロミスオブジェクトの結果を指定します。上記では、123になります。
このテストを実行すると結果は以下のように成功します。
C:\Users\xxx\Documents\vscode\apps>mocha index.js Promiseテスト √ Promiseのテスト1 1 passing (23ms)
chaiのエラー出力情報を無制限にする
chaiでエラーがでたとき{Objects}、、、というように簡素化されて表示されるのでObjectのどこが一致していないのか判断しづらいです。これを無制限に出力するには以下を記述することでObjectの中身を出力してくれるようになります。
chai.config.truncateThreshold = 0;
テストする
期待値と実際値を比較しますが、方法は無数にあります。
chai.expect(expected).to.be.null;// expectedがnullならpass
chai.expect(actual).to.equals(expected);// expectedとactualが等しいならpass
chai.expect(actual).to.equal(expected);// expectedとactualが等しいならpass
chai.expect(actual).to.not.equal(expected);// expectedとactualが等しくないならpass
chai.expect(actual).to.be.an('array');// actualが配列ならpass
chai.expect(actual).to.be.greaterThan(expected);// actual > expectedならpass (数値)
chai.expect({ojb:3}).to.deep.equal({ojb:3});// 比較する値がオブジェクトのばあいはあの場合はto.deep.equalで比較する
chai.expect(stub.callCount).to.equal(1);// sinon.stubメソッドが実行された回数を比較
chai.expect({'Message':'aiueo'}).to.have.property('Message');// プロパティにMessageが存在する場合pass
chai.expect('111').to.have.lengthOf(3);// 文字列長が3であるかどうかを比較
chai.assert.operator(-1, '<', 3);
chai.assert.closeTo(2.5,3,0.5);
chai.assert.deepEqual({},{});// 第一引数のオブジェクトと第二引数のオブジェクトを比較し、同じならpass
chai.assert.notDeepEqual({},{'a':true});// 第一引数のオブジェクトと第二引数のオブジェクトを比較し、異なればpass
chai.assert.isFalse(bool); // boolがfalseかどうかを比較
chai.assert.isTrue(bool); // boolがtrueかどうかを比較
chai.assert..isUndefined(data);// dataがundefinedならpass
chai.assert.match(actual, /^aiueo/);// 正規表現でaiueoで始まる文字列ならpass
chai.assert.match(actual, /aiueo$/);// 正規表現でaiueoで終わる文字列ならpass

KHI入社して退社。今はCONFRAGEで正社員です。関西で140-170/80~120万から受け付けております^^
得意技はJS(ES20xx),Java,AWSの大体のリソースです
コメントはやさしくお願いいたします^^
座右の銘は、「狭き門より入れ」「願わくは、我に七難八苦を与えたまえ」です^^



コメント