アルゴリズムとかオーダーとか

仕事で勉強したことなどをまとめてます

Node.jsのtestでsinonを使ってspyする

今回の記事はNode.jsのTest用ライブラリの紹介です。
Node.jsでtestを書く時に今までmochaとchaiを使ってきました。今回はconsole.warnの呼び出しをspyしたくてどうやったらいいのか?を調べていた時にこのライブラリを発見しました。
sinonjs.org

ちょっと触った感じ、非常に使いやすいmockupツールだと思います。以降はconsole.warnをspyすることを題材にして使い方を説明します。

前提条件

console.warnをなんでspyするの?

とあるライブラリを作る場合、ユーザに問題がある状況を正確に伝えたいことがあります。その時にconsole.warnやconsole.errorを使います。
今回はこのconsole.warnでの出力に問題があったのでそのテストを書く必要が出てきました。

自前でmockに置き換えるのはダメなの?

僕のNode.js Javascript力が足りなくてできませんでした。globalにあらかじめ定義されている標準ライブラリは簡単に置き換えができないようになっているみたいです。

mocha 前提

多分mocha以外でも動くとは思いますが。今回の記事はmocha上で使う前提となっています。

sinonのインストール

いつも通りnpmでインストールします。

npm i -D sinon

sinonをロード

sinonの機能を使いたいtest.jsでsinonをロードします。

const sinon = require('sinon')

beforeEachでspyしてafterEachでお片づけ

今回はconsole.warnが呼び出されたかどうかをチェックしたいのでbeforeEachでspyをセットします。
テストごとに状態をリセットしたいのでafterEachでsinonをリセットします。

  let spy
  beforeEach(() => {
    spy = sinon.spy(console, 'warn')
  })
  afterEach(() => {
    sinon.restore()
  })

spyでassertする

spyでは対象のメソッドが呼び出されたかどうかをチェックすることができます。また、特定の引数で呼び出されたかどうかもチェックできます。

  describe('console.warn check', () => {
    it('no problem case', async() => {
      someOfFunction()
      assert.equal(false, spy.calledWith('Warning message'))
    })
    it('warning case.', async() => {
      someOfWarningFunction()
      assert.equal(true, spy.calledWith('Warning message'))
    })

まとめ

spy以外にもmockやstubといったTDDで必要なinjection機能を備えています。またいろいろなassertionも持っています。より詳しい使い方は公式のドキュメントを参照ください。

Node.jsでのTDD3種の神器がmocha, chai, sinonっぽいですね。sinonについては今まで知らなかった(javascriptはmockしやすいから知らなくてもあんまり困らなかった)けど、実際使ってみると非常に便利なのでこれからは積極的に使っていこうと思いました。