JestによるNode.js（サーバサイド）のテストコード

# Jest - JavaScriptのテストフレームの使い方

## 公式サイト
- [jestを利用](https://jestjs.io/docs/ja/getting-started)

## 使い方

### インストール
プロジェクト毎ではなく、端末にjestそのものをインストール。
プロジェクト毎のインストールでもOK。その場合はオプション不要。

```bash
npm install jest --global
```
​
## テストファイルの置き場所（推奨）

理由：
プロジェクト配下に置く。
ライブラリをモックする時にプロジェクト外だとモックできないため

```
node-project/
　├ node_modules
　├ src/
　│　├ testTarget.js　         ※テスト対象のJS
　│　└ testTargetClass.js　    ※テスト対象のJS
　├ test-jest/               　※このディレクトリ作成を作成するかは任意
　│　├ testTarget.test.js      ※テスト
　│　└ testTargetClass.test.js ※テスト
　├ app.js
　├ package-lock.json
　└ package.json
```
​
### テストファイルの名称
ファイル名に<任意名称>.test.jsと命名すること

```:
xxx.test.js
```
​
## テスト記述方法

同期メソッド（async）がついていないメソッドを呼び出す場合は、
以下サンプルのテストコードのasyncとdone, awaitを削除すればよい。
​
## テストの記述方法_関数_Asyncを呼び出す時
​
テスト対象

```js:testTarget.js
// テスト対象
let asyncFunction = async function () {
    let response = await somethingFromLib();
    response = {
        expeced : "この値になるばず"
    };
    return response;
};
module.exports =  asyncFunction;
```
​
テストコード

```js:testTarget.test.js
// テストファイル内で使用するライブラリを読み込む
const log4js = require('log4js');
​
// テスト対象を読み込む_相対パス
const testfile = require('../src/testTarget');
​
/** テストの書き方 非同期の関数を呼び出す時　asyncをつける*/
test('async関数を呼び出す時', async (done) => {
​
    const result = await testfile.asyncFunction();
​
    // 期待される値を記述
    const expected = {
        expeced : "この値になるばず"
    };
​
    // テスト結果の確認
    expect(result).toEqual(expected);
​
    // 最後Doneを呼び出す
    done();
});
​
```
​
## テストの記述方法_クラス関数_Asyncを呼び出す時

テスト対象

```js:testTargetClass.js
class sampleClass {
    constructor(value) {
        this.value = value;
    };
​
    // テスト対象
    async asyncfunc(){
        let result await somethingFromLib();
        result = {
            constractor : this.value,
            result : "何かの値"
        };
        return result;
    }
​
}
module.exports = sampleClass;
```

テストコード


```js:testTargetClass.test.js
// テストファイル内で使用するライブラリを読み込む
const log4js = require('log4js');
​
// テスト対象を読み込む_相対パス
const target = require('../src/testTargetClass');
​
/** テストの書き方 非同期の関数を呼び出す時　asyncをつける*/
test('async関数を呼び出す時', async (done) => {
    const initialValue = "コンストラクタ";
    // クラスをインスタンス化する
    new testclass = new target(initialValue);
    //　テスト対象の呼び出しを行う
    const result = await testclass.asyncfunc();
​
    // 期待される値を記述
    const expected = {
            constractor : initialValue,
            result : "何かの値"
        };
​
    // テスト結果の確認
    expect(result).toEqual(expected);
​
    // 最後Doneを呼び出す
    done();
});
​
```
​
## テスト対象で使用している関数をMockしたい場合_クラス関数の場合
​

テスト対象

```js:testTargetClass.js
class sampleClass {
    constructor(value) {
        this.someValue = value;
    };
​
    // テスト対象
    async asyncfunc(){
        return await someMethodFromSameClass();
    };
​
    // モック対象
    async someMethodFromSameClass(){
        <!-- some code... -->
        return something;
    };
​
}
module.exports = sampleClass;
```

テストコード


```js:testTargetClass.test.js
​
// テストファイル内で使用するライブラリを読み込む
const log4js = require('log4js');
​
// テスト対象を読み込む_相対パス
const target = require('../src/testTargetClass');
​
/** テストの書き方 非同期の関数を呼び出す時　asyncをつける*/
test('async関数を呼び出す時', async (done) => {
    const initialValue = "コンストラクタ";
    // クラスをインスタンス化する
    new testclass = new target(initialValue);
​
    // モックを定義する
    const spy = jest.spyOn(testclass, "someMethodFromSameClass")
    .mockImplementation(() => {
        return {
            constractor : "コンストラクタ",
            result : "you have been mocked"
        };
    });
    
​
​
    //　テスト対象の呼び出しを行う
    const result = await testclass.asyncfunc();
​
    // 期待される値を記述
    const expected = {
            constractor : initialValue,
            result : "you have been mocked"
        };
​
    // テスト結果の確認
    expect(result).toEqual(expected);
​
    // モックが1回だけ実行されたことを確認
    expect(spy).toHaveBeenCalled();
    // mockのリセット
    spy.mockRestore();
​
    // 最後Doneを呼び出す
    done();
});
​
```
​
### テストの実行方法

特定のテストファイルのみを実行する時


```:
>/node-project/test-jest/
jest testTarget.test.js
```
​
すべてのテストファイルを一度に実行する時
※テストは非同期実行されることになる


```:
>/node-project/test-jest/
jest
```