node.jsのソースを単体テストする際のmocha+sinonの使い方

node.jsのソースを単体テストする際のmocha+sinonの使い方

node.jsのソースをmochaでテストしているとsinonでモックしてテストする、といったケースがあると思います。

node.jsのソースを単体テストする際のmocha+sinonの使い方

sinonは英語ドキュメントもありますし、広く使われているモジュールなのでモックの方法がネットにごろごろ転がっています。

sinonでメソッドをモックする

簡単なソースでsinonを試してみたいと思います。

以下をindex.jsで保存します。

exports.sampleという変数にtestMethodを代入します。これでtestMethodをsampleという名前で他のモジュールからも使えるようにします。

このtestMethodの戻り値をsinonでモックしてみます。

以下、index.test.jsです。

stub.returnsで戻り値を指定しているので、これでモックができたことになります。

そのあとにsample()を実行すると引数が何であっても戻り値は指定した戻り値となります。

結果は以下のようになります。

node.jsのソースを単体テストする際のmocha+sinonの使い方

sinonでメソッド内のメソッドをモックする

実際はメソッド内にあるDBに検索するメソッドなどをモックするというケースが多いかと思います。

以下はメソッド内のメソッドをモックする例です。

getTaxは通常はDBから取得すると思いますが、モックできるかのテストなので1.08を返すだけにしました。

index.test.jsで1.08を返すのをスタブ化し、1.10を返すようにしています。テスト自体はtestMethodメソッドから実行しています。

sandboxでオブジェクトのキーに対するプロパティをモックする

sinon.sandbox.create()メソッドでsandboxオブジェクトを返します。

sandbox.create() is deprecated (非推奨となっています)

変わりにrequire('sinon').createSandbox()メソッドを使用します。

このように記述するとオブジェクトのキーに対するプロパティをモックすることができます。

以下、実行例です。

結果は成功します。

node.jsのソースを単体テストする際のmocha+sinonの使い方

sandbox.stubでPromiseの結果をモックする

AWS.Service.prototypeのmakeRequestをモックします。返すのはrejectするかresolveするかです。
  const stub = sandbox.stub(AWS.Service.prototype, ‘makeRequest’)
    stub.returns({
      promise: () => {
        return Promise.reject()
      }
  })

sinonのエラー

Cannot stub non-existent own property XXX

…XXXというメソッドがない場合にこのエラーが発生する。

TypeError: Attempted to wrap execute which is already wrapped

…すでにモックしているものをもう一度モックしようとすると発生する。

sinonの評価はmocha+chaiの使い方を参照して下さい。

process.env(環境変数)をモックする方法

process.env(環境変数)をモックするにはsandboxを使用します。

createSandboxメソッドでsandboxを作成し、afterEachでサンドボックスのrestoreします。

afterでsinonのリストアをします。

const sinon = require('sinon') // sinon作成
const sandbox = require('sinon').createSandbox() //sandbox作成
afterEach(()=>{
sandbox.restore()// sandboxをリストアすること
})
after(()=>{
sinon.restore() // sinonをリストアすること
})

view raw
gistfile1.txt
hosted with ❤ by GitHub

上記で環境変数PATHの値を変えることができます。但し、環境変数がPCに設定されていない場合は以下のようなエラーとなります。

以下、実行例です。

const chai = require('chai')
const sinon = require('sinon')
const sandbox = sinon.createSandbox()
const expect = chai.expect
describe('sinon', function () {
it('sinonのテスト', function(){
sandbox.stub(process.env, 'PATH').value('12345')
expect(process.env.PATH).to.equal('12345') // passになる
})
afterEach(function () {
sandbox.restore()
});
after(function () {
sinon.restore()
})
})

view raw
gistfile1.txt
hosted with ❤ by GitHub

オブジェクトをモックする

sinon.stubメソッドは第一引数でオブジェクトだけを指定することができます。

この場合、targetが持つすべてのメソッドをモックすることになります。

targetはaaa,bbb,cccと言うメソッドを持つとします。その場合、以下のように全てのメソッドをrestore()する必要があります。

参考サイト

メソッドの戻り値を動的に変更する

メソッドをモックすることができますが、1回目の戻り値と2回目の戻り値を変更したい場合があります。

以下のようにonCallメソッドを使用します。

onCall(0)が1回目の戻り値になります。

onCall(1)が2回目の戻り値になります。

sinonのアサーション

sinonには標準でアサーションが用意されています。

sinon.assert.called(index.tax) // 呼ばれたことの検証
sinon.assert.calledOnce(index.tax) // 1回呼ばれたことの検証
sinon.assert.notCalled(index.tax) // 呼ばれていないことの検証
sinon.assert.calledTwice(index.tax) // 2回呼ばれたことの検証
sinon.assert.callOrder(index.tax, index.age) // スタブしたメソッドの呼ばれた順序の検証
sinon.assert.callCount(index.tax, 3) // スタブしたメソッドの呼ばれた回数の検証

view raw
gistfile1.txt
hosted with ❤ by GitHub

スポンサーリンク
  • このエントリーをはてなブックマークに追加
  • Evernoteに保存Evernoteに保存
スポンサーリンク

コメントをどうぞ

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA