nodeunit で始めるNodejs の単体テスト自動化

# Unit test 
nodejs の単体テストライブラリ`nodeunit` を使って、単体テスト自動化の初歩について説明していきます。

## テストの概要 
本セクションでは、次のようなテスト方法について、実際の簡単なプログラムをテストすることで説明していきます。

* 同期的な処理のテスト(基本的なテスト)
* 例外がスローされるかどうかの処理のテスト
* 非同期な処理のテスト
* setUp, tearDown を使ったテストコードのリファクタリング

## nodeunit のインストール 
`nodeunit` をインストールします。

```text
$ sudo npm install -g nodeunit
```


インストールが完了したら、`nodeunit` コマンドを実行して問題なく実行されることを確認してみましょう。


```text:nodeunit
$ nodeunit -v
0.9.1
```


もしコマンドが見つからない場合、nodeunit コマンドに対してPATH を通すなりを各自行ってください(環境依存な部分なので、詳細な手順は省略します)。

## 作業ディレクトリの作成 
今回のディレクトリ/ファイル構成は次のようにします。


```text:ディレクトリ構成
nodeprj/                // <- ワークディレクトリ
  +--lib/
  | +--divided.js       // <- テスト対象のプログラム
  +--test/
    +--test-divided.js  // <- divided.js をテストするプログラム
```

これらのディレクトリとファイルは事前に作成するようにしておいてください。


```text:テストのためのディレクトリ作成
$ mkdir -p nodeprj
$ cd nodeprj
$ mkdir {lib,test}
```


今回作成するのは、与えられた数値を2 で割って、小数点以下を切り捨てた物を計算するプログラムをテスト駆動型(TDD)で開発していく仮定を例に、`nodeunit` の使い方について説明していきたいと思います。

## 同期的な処理のテスト 
`test/test-divided.js` ファイルを新規作成し、以下のテストプログラムを記述します。
テストプログラムを記述するときは、モジュール内で共有される`exports` オブジェクトにメソッドを代入していく形式でやっていきます。
`test.equal` はアサーションを行うメソッドで、ここにテストの想定する結果を記載します。
また、各テストケースの終了時には`test.done` メソッドが呼ばれるようにしてください。


```javascript:test/test-divided.js
var divided = require('../lib/divided');

exports['calculate'] = function(test) {
    test.equal(divided.calculate(4), 2);
    test.done();
};
```


プログラムを作成したら`nodeunit` コマンドでテストを実行しましょう。
`nodeunit` コマンドを実行するときは`nodeunit "テストプログラムが入っているディレクトリ"` という形式で実行します。
今回は`test` ディレクトリにテストプログラムが入っているので、`nodeunit test` とコマンドを実行します。


```javascript:nodeunit
~nodeprj$ nodeunit test

module.js:340
    throw err;
          ^
Error: Cannot find module '../lib/divided'
    at Function.Module._resolveFilename (module.js:338:15)
    at Function.Module._load (module.js:280:25)
    ...
    at Module.require (module.js:364:17)
```


結果を見るとモジュールの呼び出しに失敗していることがわかります。
このテスト結果を参考に、まずは`lib/divided.js` ファイルを作成し、`calculate` メソッドを実装してみましょう。


```javascript:lib/divided.js
/** 与えられた値を2 で割って小数点以下を切り捨てた結果を返す関数 */
exports.calculate = function(num) {
};
```


上記のファイルを作成したら、再度`nodeunit` を実行します。
![NodeUnite_Intro_0000.png](https://qiita-image-store.s3.amazonaws.com/0/70152/ceead102-414a-8f41-e6bd-8e1ad0af126c.png)


すると、想定した結果が2 であるのに対し、`undefined` が返ってきているためエラーとなっています。
もう一度`divided.js` ファイルを開き処理を追加してみましょう。


```javascript:lib/divided.js
/** 与えられた値を2 で割って小数点以下を切り捨てた結果を返す関数 */
exports.calculate = function(num) {
    return num / 2;
};
```


テストを実行してみます。


```text:nodeunittest
$ nodeunite test
```


![NodeUnite_Intro_0001.png](https://qiita-image-store.s3.amazonaws.com/0/70152/ece992dc-17fc-2ba8-b0b0-8818def1cb1f.png)


テストに成功しました。それでは次のテストとして、計算結果が割り切れなかった場合に小数点以下を切り捨てられるかどうかのテストを追加してみます。


```javascript:test/test-divided.js
var divided = require('../lib/divided');

exports['calculate'] = function(test) {
    test.equal(divided.calculate(4), 2);
    test.equal(divided.calculate(3), 1);
    test.done();
};
```


`nodeunit test` を実行します。


```javascript:nodeunittest
$ nodeunit test

test-divided
✖ calculate

AssertionError: 1.5 == 1
    at Object.equal (/usr/local/lib/node_modules/nodeunit/lib/types.js:83:39)
    at Object.exports.calculate (/opt/nodeprj/test/test-divided.js:5:10)
    ......
    at _concat (/usr/local/lib/node_modules/nodeunit/deps/async.js:512:9)


FAILURES: 1/2 assertions failed (7ms)
```


すると上記のように、1 が返ることを想定していたところ、1.5 が返ってきたためエラーとなっています。
上記結果を参考に、プログラムに小数点以下を切り捨てる処理を追加します。


```javascript:lib/divided.js
/** 与えられた値を2 で割って小数点以下を切り捨てた結果を返す関数 */
exports.calculate = function(num) {
    return Math.floor(num / 2);
};
```


`nodeunit test` を実行します。


```javascript:nodeunittest
~nodeprj$ nodeunit test

test-divided
✔ calculate

OK: 2 assertions (5ms)
```


これで小数点以下を切り捨てる処理の実装は完了です。

## 例外を判定するテストを作成する(数値じゃないものが渡された時に例外を投げる処理のテスト/実装) 
数値以外の値がメソッドの引数に渡されたら例外を投げる処理のテスト/実装を行います。
例外がスローされるかどうかの試験をする場合は`test.throws` メソッドの引数に例外をスローするメソッドを渡して実行します。


```javascript:lib/divided.js
var divided = require('../lib/divided');

exports['calculate'] = function(test) {
    test.equal(divided.calculate(4), 2);
    test.equal(divided.calculate(3), 1);
    test.throws(function() { divided.calculate(); });
    test.throws(function() { divided.calculate(null); });
    test.throws(function() { divided.calculate("abc"); });
    test.throws(function() { divided.calculate([]); });
    test.done();
};
```



```javascript:nodeunittest
$ nodeunit test

test-divided
✖ calculate

AssertionError: undefined  "Missing expected exception.."
    at _throws (/usr/local/lib/node_modules/nodeunit/lib/assert.js:329:5)
    at assert.throws (/usr/local/lib/node_modules/nodeunit/lib/assert.js:346:11)
    ...
    at iterate (/usr/local/lib/node_modules/nodeunit/deps/async.js:123:13)

AssertionError: undefined  "Missing expected exception.."
    at _throws (/usr/local/lib/node_modules/nodeunit/lib/assert.js:329:5)
    at assert.throws (/usr/local/lib/node_modules/nodeunit/lib/assert.js:346:11)
    ...

FAILURES: 4/6 assertions failed (26ms)
```


想定した例外がスローされていないためテストが失敗しています。
`lib/divided.js` に数値以外の値が指定されたら例外をスローする処理を追加します。


```javascript:lib/divided.js
/** 与えられた値を2 で割って小数点以下を切り捨てた結果を返す関数 */
exports.calculate = function(num) {
    if (typeof num !== 'number') {
        throw new Error('Type of numeric is expected.');
    }
    return Math.floor(num / 2);
};
```


例外をスローする処理を追加したら、テストを実行します。


```javascript:nodeunittest
$ nodeunit test

test-divided
✔ calculate

OK: 6 assertions (5ms)
```


成功しました。

## 非同期処理のテストをする(標準入力から値を受け取ってコンソールに出力する処理のテスト/実装) 
非同期で標準入力から値を読み込むプログラムをテストします。
今回は標準入力から値を受け取り、計算結果を`console.log` で結果をコンソールに出力するプログラムのテストケースを追記します。
まずは今までと同じようにテストケース`read a number` を追加してみましょう。
標準入力から渡された数値を計算し、その結果を`console.log` で標準出力するという処理ということにしておきます。


```javascript:test-divided
var divided = require('../lib/divided');
var events = require('events');

exports['calculate'] = function(test) {
    test.equal(divided.calculate(4), 2);
    test.equal(divided.calculate(3), 1);
    test.throws(function() { divided.calculate(); });
    test.throws(function() { divided.calculate(null); });
    test.throws(function() { divided.calculate("abc"); });
    test.throws(function() { divided.calculate([]); });
    test.done();
};

exports['read a number'] = function(test) {
    var ev = new events.EventEmitter();

    process.openStdin = function() { return ev; };
    process.exit = test.done;
    var _console_log = console.log;
    console.log = function(str) {
        console.log = _console_log;
        test.equal(str, 'result: 4');
    };

    divided.read();
    ev.emit('data', '8');
};
```


上記のサンプルコードでは、EventEmitter を使用して`data` イベントを発生させることにより、標準入力をエミュレートするものです。
divided には、この後記載しますが、標準入力から与えられた8 を2 で割って標準出力に`result: 4` と出力されることを想定した内容になっています。

標準出力へは`console.log` を使って出力するので、console.log メソッドをstub なメソッドで上書きし、stub の中で想定した通りの値がconsole.log の引数として渡されたかどうかをアサートしています。
また、今回は標準出力で`console.log` をstub で上書きしているので、テストを実施したら`console.log` を元の状態に戻しておきます。
そのため今回は、一旦`console.log` メソッドの参照を`_console_log` 変数に退避しておき、stub 内で元に戻すようにしています。


```text:該当箇所
    var _console_log = console.log;
    console.log = function(str) {
        console.log = _console_log;
        ...
```


それではテストを実行してみましょう。


```text:テストの実行結果
~nodeprj$ nodeunit test

test-divided
✔ calculate
TypeError: Object #<Object> has no method 'read'
    at Object.exports.read a number (/path/to/nodeprj/test/test-divided.js:25:13)
    at Object.<anonymous> (/usr/local/lib/node_modules/nodeunit/lib/core.js:236:16)
    at /usr/local/lib/node_modules/nodeunit/lib/core.js:236:16
    ......
```


`lib/divided.js` の`read` メソッドが定義されていないためテストに失敗しました。
`lib/divided.js` に`read` メソッドを追加していきましょう。


```javascript:lib/divided.js
/** 与えられた値を2 で割って小数点以下を切り捨てた結果を返す関数 */
exports.calculate = function(num) {
    if (typeof num !== 'number') {
        throw new Error('Type of numeric is expected.');
    }
    return Math.floor(num / 2);
};

/** 標準入力から値を受け取り、計算結果を返すメソッド */
exports.read = function() {
    var stdin = process.openStdin();
    stdin.on('data', function(chunk) {
        var param = parseFloat(chunk);
        var result = exports.calculate(param);
        console.log('result: ' + result);
        process.exit();
    });
};
```


テストを実行します。


```javascript:nodeunittest
$ nodeunit test

test-divided
✔ calculate
✔ read a number

OK: 7 assertions (6ms)
```


テストに成功しました。

……が、今回このテストは不完全な状態です。
今回たまたま全部のassertions 7個("calculate" 6 個、"read a number" 1 個) が実行され、結果がOK となりましたが、"read a number" でテストをしている`read` メソッドは非同期で実行されるため、場合によっては全部で6 個しか実行されないでテストが終了してしまう可能性があります(今回の実行環境では再現させることができませんでした)。しかもそれはテスト結果としてOK となってしまいます。
もし非同期で実行されなかったテストケースがNG 出会った場合、テストでその障害を発見できない可能性が出てきてしまいます。

それを解消するために`test.expect` メソッドを使用して、事前に"read a number テストケースには1 つのassertion があるよ!" ということをテストケースに通知することができるようになっています
テストケースに対して幾つのassertion があるかを通知するには`expect` メソッドを使います。

では、実際にテストプログラム側を修正してみましょう。
以下のテストプログラムはテストケース開始時に`test.expect` メソッドで1 個のassertion があるということを事前に通知し、現在のテストケースで幾つのassertion があるかをnodeunit に伝えることができます。


```text:test/test-divided.js
var divided = require('../lib/divided');
var events = require('events');

exports['calculate'] = function(test) {
    test.equal(divided.calculate(4), 2);
    test.equal(divided.calculate(3), 1);
    test.throws(function() { divided.calculate(); });
    test.throws(function() { divided.calculate(null); });
    test.throws(function() { divided.calculate("abc"); });
    test.throws(function() { divided.calculate([]); });
    test.done();
};

exports['read a number'] = function(test) {
    test.expect(1);
    var ev = new events.EventEmitter();

    process.openStdin = function() { return ev; };
    process.exit = test.done;
    var _console_log = console.log;
    console.log = function(str) {
        console.log = _console_log;
        test.equal(str, 'result: 4');
    };

    divided.read();
    ev.emit('data', '8');
};

```


`nodeunit test` を実行してみましょう。


```text
$ nodeunit test

test-divided
✔ calculate
✔ read a number

OK: 7 assertions (19ms)
```


上記のように`OK: 7 assertions` と表示されれば、しっかりと7 箇所のassertion が実行されたうえでOK になっているということが確認できます。

### assertion の数がtest.expect で指定した数より少なかった場合 
今回、`test.expect` メソッドを使ってこのテストケースがassertion を1 つ持つということを通知していましたが、もし`test.expect` で指定した数とassertion の数が異なっていた場合、どのようになるかを擬似的に確認してみましょう。

上記のテストケースのうち、テストプログラムの`test.expect` をコメントアウトし、`test.equal` もコメントアウトし、テストを実行してみましょう。


```text:test/test-nodejs.js
var divided = require('../lib/divided');
var events = require('events');

exports['calculate'] = function(test) {
    test.equal(divided.calculate(4), 2);
    test.equal(divided.calculate(3), 1);
    test.throws(function() { divided.calculate(); });
    test.throws(function() { divided.calculate(null); });
    test.throws(function() { divided.calculate("abc"); });
    test.throws(function() { divided.calculate([]); });
    test.done();
};

exports['read a number'] = function(test) {
    // test.expect(1);
    var ev = new events.EventEmitter();

    process.openStdin = function() { return ev; };
    process.exit = test.done;
    var _console_log = console.log;
    console.log = function(str) {
        console.log = _console_log;
        // test.equal(str, 'result: 4');
    };

    divided.read();
    ev.emit('data', '8');
};
```



```text:nodeunittest
$ nodeunit test

test-divided
✔ calculate
✔ read a number

OK: 6 assertions (21ms)
```


すると、`calculate`, `read a number` のテストケースが実行され、全体でassertion が6 件実行され、テスト結果OK が返ってきています。
が、実際このテストでは`read a number` テストケースに1 つもassertion が入っていないのにテストがOK になっているということになります。

それでは次に`text.expect` のコメントアウトはそのままで、`test.equal` のコメントを解除してテストを実行すると、どのような動きになるか確認してみましょう。


```text:test/test-divided.js
......
exports['read a number'] = function(test) {
    // test.expect(1);
    var ev = new events.EventEmitter();
    ......
    console.log = function(str) {
        console.log = _console_log;
        test.equal(str, 'result: 4');    // <-- コメントアウトを解除
    };
    ......
};
```



```text:nodeunittest
$ nodeunit test

test-divided
✔ calculate
✔ read a number

OK: 7 assertions (6ms)
```


すると、7 個のassertion が実行されて結果がOK となりました。
これは、`test.equal` のassertion が実行される/されないといった事はテストをpass するかどうかに関係が無く、この項目が非同期処理によって実行されなかったとしても見た目上はテストOK となってしまう危険性をはらんでいます。
この危険性を回避するために`test.expect` を使って想定した件数のassertion が実行されなかった場合にNG とするようにします。

それではそれを確認するために`test.expect(1);` の部分のコメントアウトを解除して、`test.equals` の部分をコメントアウトしてテストケースを実行してみましょう。


```text:test/test-nodejs.js(一部抜粋)
......
exports['read a number'] = function(test) {
    test.expect(1);          // <-- コメントアウトを解除
    var ev = new events.EventEmitter();
    ......
    console.log = function(str) {
        console.log = _console_log;
        // test.equal(str, 'result: 4');    // <-- コメントアウト
    };
    ......
};
```



```text:nodeunittest
$ nodeunit test

test-divided
✔ calculate
✖ read a number

Error: Expected 1 assertions, 0 ran
    at process.test.done [as exit] (/usr/local/lib/node_modules/nodeunit/lib/types.js:121:25)
    at EventEmitter.<anonymous> (/opt/nodeprj/lib/divided.js:16:17)
    ......

FAILURES: 1/7 assertions failed (8ms)
✖ read a number
......
```


すると、1 個のassertion が実行されることが期待されているが、0 個のassertion が実行されたというエラーが出ます。
このようにして非同期処理によってassertion が実行されなかった場合でも、テストケースをNG として検知することができるようになります。


## 複数のテストケースで共有される変数について 
次は複数テストケースを追加していった時に共有されるデータについて注意する点について説明していきたいと思います。
複数のテストケース間で共有されるデータについて認識していないままテストケースを作成してしまうと想定しない動きとなることがあります。
そのことについて確認するために、次のような、標準入力から値を受け取る非同期メソッドが数値以外を受け取った時に例外をスローするケースを追加して説明していきたいと思います。


```javascript:test/test-divided.js
var divided = require('../lib/divided');
var events = require('events');

exports['calculate'] = function(test) {
    test.equal(divided.calculate(4), 2);
    test.equal(divided.calculate(3), 1);
    test.throws(function() { divided.calculate(); });
    test.throws(function() { divided.calculate(null); });
    test.throws(function() { divided.calculate("abc"); });
    test.throws(function() { divided.calculate([]); });
    test.done();
};

exports['read a value other than a number'] = function(test) {
    test.expect(1);
    var ev = new events.EventEmitter();

    process.openStdin = function() { return ev; };
    process.exit = test.done;
    divided.calculate = function() {
        throw new Error('Expected a number');
    };
    var _console_log = console.log;
    console.log = function(str) {
        console.log = _console_log;
        test.equal(str, 'Error: Expected a number');
    };
    divided.read();
    ev.emit('data', 'asdf');
};

exports['read a number'] = function(test) {
    test.expect(1);
    var ev = new events.EventEmitter();

    process.openStdin = function() { return ev; };
    process.exit = test.done;
    var _console_log = console.log;
    console.log = function(str) {
        console.log = _console_log;
        test.equal(str, 'result: 4');
    };

    divided.read();
    ev.emit('data', '8');
};
```


テスト対象プログラムに例外をスローする処理を追加し、テストを実行します。


```javascript:lib/divided.js
/** 与えられた値を2 で割って小数点以下を切り捨てた結果を返す関数 */
exports.calculate = function(num) {
    if (typeof num !== 'number') {
        throw new Error('Type of numeric is expected.');
    }
    return Math.floor(num / 2);
};

/** 標準入力から値を受け取り、計算結果を返すメソッド */
exports.read = function() {
    var stdin = process.openStdin();

    stdin.on('data', function(chunk) {
        var param = parseFloat(chunk);
        try {
            var result = exports.calculate(param);
            console.log('result: ' + result);
        } catch(e) {
            console.log(e);
        }
        process.exit();
    });
};
```



```text:nodeunitetest
$ nodeunit test

test-divided
✔ calculate
✔ read a value other than a number
✖ read a number

AssertionError: [Error: Expected a number] == 'result: 4'
    at Object.equal (/usr/local/lib/node_modules/nodeunit/lib/types.js:83:39)
    at Console.console.log (/opt/nodeprj/test/test-divided.js:41:14)
    at EventEmitter.<anonymous> (/opt/nodeprj/lib/divided.js:19:21)
    ...


FAILURES: 1/8 assertions failed (9ms)
✖ read a number
...
```


すると、`calculate`, `read a value other than a number` テストケースについては成功していますが、`read a number` テストについては失敗してしまいました。
失敗した原因としては、EventEmitter で数値を標準入力に渡していますが、`[Error: Expected a number]` な例外がスローされていることによります。

テストケース`read a number` は先ほどまでは成功していたテストケースですが、今回新しいテストケース`read a value other than a number` を`read a number` テストケースの前に入れることで、失敗するようになってしまいました。
これは`read a value other than a number` テストケースでstub を設定している部分がありますが、そのstub が設定されたまま`read a number` テストケースが実行されることによります。
ここでは各非同期なテストケースが実施された後に、stub を設定した変数を全て元に戻しておくように、`process.exit` が呼ばれたタイミングでstub を元に戻す処理を実行するようにしましょう。


```javascript:test/test-divides.js
var divided = require('../lib/divided');
var events = require('events');

exports['calculate'] = function(test) {
    test.equal(divided.calculate(4), 2);
    test.equal(divided.calculate(3), 1);
    test.throws(function() { divided.calculate(); });
    test.throws(function() { divided.calculate(null); });
    test.throws(function() { divided.calculate("abc"); });
    test.throws(function() { divided.calculate([]); });
    test.done();
};

exports['read a value other than a number'] = function(test) {
    test.expect(1);
    var ev = new events.EventEmitter();

    var _process_openStdin  = process.openStdin;
    process.openStdin       = function() { return ev; };
    var _process_exit       = process.exit;
    process.exit = function() {
        // テストケース終了時にstub を元に戻す
        process.openStdin   = _process_openStdin;
        process.exit        = _process_exit;
        divided.calculate   = _divided_calculate;
        console.log         = _console_log;
        test.done();
    };

    var _divided_calculate = divided.calculate;
    divided.calculate = function() {
        throw new Error('Expected a number');
    };

    var _console_log = console.log;
    console.log = function(str) {
        test.equal(str, 'Error: Expected a number');
    };

    divided.read();
    ev.emit('data', 'asdf');
};

exports['read a number'] = function(test) {
    test.expect(1);
    var ev = new events.EventEmitter();

    var _process_openStdin  = process.openStdin;
    process.openStdin       = function() { return ev; };
    var _process_exit       = process.exit;
    process.exit = function() {
        // テストケース終了時にstub を元に戻す
        process.openStdin   = _process_openStdin;
        process.exit        = _process_exit;
        console.log         = _console_log;
        test.done();
    }

    var _console_log = console.log;
    console.log = function(str) {
        test.equal(str, 'result: 4');
    };

    divided.read();
    ev.emit('data', '8');
};
```


テストプログラムを書き換えたら`nodeunit test` を実行します。


```javascript:nodeunittest
$ nodeunit test

test-divided
✔ calculate
✔ read a value other than a number
✔ read a number

OK: 8 assertions (7ms)
```


全てのテストケースで成功OK が返ってきました。
また上記のテストケース実行結果を見ると、テストケース内に非同期な処理がある場合でも、各テストケース間はシーケンシャルに実行されていることが確認できると思います。
このようにテストケース間はシーケンシャルであるために、毎回テストケースの値を初期化することで、次のテストケースに影響を及ぼさず、独立したstub 環境でテストを走らせることができるようになります。
もしテストケース間が並行に実行されてしまうようなことがあった場合、テストケース`read a value other than a number` がstub を元に戻す前に`read a number` が実行されてしまい、正しくテストができない可能性が出てきてしまいます。


## テストケースにsetUp, tearDown を実装する 
今まで作成してきたテストケースではストケースが開始する時と、各テストケースが終了するときに必要な処理(stub の作成等) をテストケースの処理内部に直接書いていましたが、`setUp`, `tearDown` メソッドを使用することで、それを1 箇所にまとめて共通化することができます。
`setUp` メソッドは各テストケースが実行される前に実行されるメソッドで、`tearDown` メソッドは各テストケースが終了するときに実行されるメソッドです。

`setUp`, `tearDown` を利用するにあたり、`nodeunit` ライブラリへのパスを通しておく必要があります。
`nodeunit` ライブラリを使用できるようにするために`~/.node_libraries` ディレクトリに`nodeunit` ライブラリのコピー/シンボリックリンクを作成する、`NODE_PATH` 環境変数に`nodeunit` のライブラリがあるディレクトリを指定する等、事前にセットアップを実施しておいてください。

それでは`setUp`, `tearDown` メソッドを使ってテストプログラムを作成してみましょう。
`setUp`, `tearDown` メソッドを実装するには、`require('nodeunit');` を最初に定義して`nodeunit` を取り入れるようにしてください。


```text:test/test-divided.js
var divided     = require('../lib/divided');
var events      = require('events');
var nodeunit    = require('nodeunit');

exports['calculate'] = function(test) {
    test.equal(divided.calculate(4), 2);
    test.equal(divided.calculate(3), 1);
    test.throws(function() { divided.calculate(); });
    test.throws(function() { divided.calculate(null); });
    test.throws(function() { divided.calculate("abc"); });
    test.throws(function() { divided.calculate([]); });
    test.done();
};

exports['read'] = nodeunit.testCase({
    setUp: function(callback) {
        // 各メソッドの参照を保持しておく
        this._process_openStdin = process.openStdin;
        this._console_log       = console.log;
        this._divided_calculate = divided.calculate;
        this._process_exit      = process.exit;

        var ev = this.ev = new events.EventEmitter();
        process.openStdin = function() { return ev; };
        callback();
    },
    tearDown: function (callback) {
        // 全てのオーバーライドしたメソッドを元に戻す
        process.opensStdin  = this._process_openStdin;
        process.exit        = this._process_exit;
        divided.calculate   = this._divided_calculate;
        console.log         = this._console_log;
        callback();
    },
    // 数値以外の数値が渡された時のテスト
    'a value other than a number': function(test) {
        test.expect(1);

        process.exit = test.done;
        divided.calculate = function() {
            throw new Error('Expected a number');
        };
        console.log = function(str) {
            test.equal(str, 'Error: Expected a number');
        };
        divided.read();
        this.ev.emit('data', 'abc');
    },
    // 数値が渡された時の正常系テスト
    'a number': function(test) {
        test.expect(1);

        process.exit = test.done;
        console.log = function(str) {
            test.equal(str, 'result: 4');
        };
        divided.read();
        this.ev.emit('data', '8');
    }
});
```


テストプログラムを作成したら、実行してみましょう。


```text:nodeunittest
$ NODE_PATH=/usr/local/lib/node_modules nodeunit test

test-divided
✔ calculate
✔ read - a value other than a number
✔ read - a number

OK: 8 assertions (9ms)
```


上記のようにテストケースをパスすれば成功です。

# 参考 
- Unit testing in node.js
    - http://caolan.org/posts/unit_testing_in_node_js/

- [node.js] Getting started with nodeunit
    - http://www.ipreferjim.com/2011/08/node-js-getting-started-with-nodeunit/

- Nodeunit
    - https://github.com/caolan/nodeunit