LoginSignup
0
0

More than 3 years have passed since last update.

Javascript + sinon スタブの実践的利用

Posted at

tl;dr

完成した関数をテストしたいが、未完成の関数をコールしているのでunit testができない。
その場合の対処です。

確認環境

  • node: v10.17.0
  • npm: 6.11.3

プロジェクトの準備

以下のコマンドを実行します。

mkdir play_utest
cd play_utest
npm init
npm i --save-dev chai mocha sinon
touch index.js index.spec.js

package.jsonを変更します。

{
  "name": "play_utest",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
-   "test": "echo \"Error: no test specified\" && exit 1"
+   "test": "mocha *.spec.js"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "chai": "^4.2.0",
    "mocha": "^6.2.2",
    "sinon": "^7.5.0"
  }
}

テスト対象のコード

index.jsを編集します。
main()関数が単体テストの対象(SUT)です。
doubleNumber()をコールしていますが、この関数はまだ中身を作っていません。

index.js
const doubleNumber = (x) => {
  // ここに、xを2倍にして返すロジックを書く予定 
  return 0; // 暫定
}

const main = (x) => {
  const answer = doubleNumber(x);
  return answer + 1;
}
module.exports.main = main

テストコード

index.spec.jsを編集します。

index.js
const sinon = require("sinon");
const expect = require("chai").expect;
const index = require('./index.js');

describe('index.js', () => {
  it('main(n)のテスト: n = {0, 5, -1}', () => {
    expect(index.main(0)).equal(1)
    expect(index.main(5)).equal(11) 
    expect(index.main(-1)).equal(-1)
  })
})

main()関数の引数に、{0, 5, -1}を渡したケースで単体テストを行いたいと考えています。
doubleNumber()関数は、暫定的に0を返すようにしているため、引数0のケースだけテストが成功しそうですが、それ以外のケースだと想定する結果になりません。

テスト対象コードを、テスト向けにリファクタ

doubleNumberをテストスタブに置き換えるため、クラスでラップします。このクラスもmodule.exportsを使って外部公開します。

index.js
const doubleNumber = (x) => {
  // ここに、xを2倍にして返すロジックを書く予定 
  return 0; // 暫定
}

const main = (x) => {
-  const answer = doubleNumber(x);
+  const answer = helpers.doubleNumber(x);
  return answer + 1;
}
module.exports.main = main

+ class Helpers{
+   doubleNumber(x) { return doubleNumber(x) }; 
+ }
+ const helpers = new Helpers();
+ module.exports.helpers = helpers;

テストコードを変更

doubleNumber()のスタブを作成します。

index.spec.js
const sinon = require("sinon");
const expect = require("chai").expect;
const index = require('./index.js');

describe('index.js', () => {
  it('main(n)のテスト: n = {0, 5, -1}', () => {
+   const stub = sinon.stub(index.helpers, 'doubleNumber');
+   stub.withArgs(0).returns(0);  // 引数が0の時、0を返す
+   stub.withArgs(5).returns(10);  // 引数が5の時、10を返す
+   stub.withArgs(-1).returns(-2);  // 引数が-1の時、-2を返す

    expect(index.main(0)).equal(1)
    expect(index.main(5)).equal(11)
    expect(index.main(-1)).equal(-1)
  })
})

テストの実行

以下のコマンドでテストを実行します。

npm test

結果:

> mocha *.spec.js

  index.js
    ✓ main(n)のテスト: n = {0, 5, -1}

  1 passing (11ms)
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0