# Jest

> [Jest/TypeScriptに関するPro eggheadレッスン](https://egghead.io/lessons/typescript-getting-started-with-jest-using-typescript)

パーフェクトなテストのソリューションはありません。とはいえ、jestは優れたTypeScriptサポートを提供する素晴らしいユニットテストのオプションです。

> 注意：単純なノードのpackage.json setupで始めることを前提としています。また、すべてのTypeScriptファイルは`src`フォルダに置かれていなければなりません。このフォルダは、きれいなプロジェクト設定のために(Jestを使わなくても)常に推奨されます。

## ステップ1：インストール

npmを使用して次をインストールします。

```
npm i jest @types/jest ts-jest -D
```

説明：

* `jest`フレームワーク(`jest`)をインストールします
* `jest`の型(`@types/jest`)をインストールします
* Jest用のTypeScriptプリプロセッサ(`ts-jest`)をインストールします。これにより、Jestはその場でTypeScriptをトランスパイルすることができ、source-mapをサポートします
* これらのすべてを、あなたのdevの依存関係に保存してください(テストはほとんど常にnpmのdev-dependencyです)

## ステップ2：Jestを設定する

次の`jest.config.js`ファイルをプロジェクトのルートに追加します：

```javascript
module.exports = {
  "roots": [
    "<rootDir>/src"
  ],
  "testMatch": [
    "**/__tests__/**/*.+(ts|tsx|js)",
    "**/?(*.)+(spec|test).+(ts|tsx|js)"
  ],
  "transform": {
    "^.+\\.(ts|tsx)$": "ts-jest"
  },
}
```

説明：

* 私達は\_すべての\_TypeScriptファイルをプロジェクトの`src`フォルダに入れることを常にお勧めします。また、これに倣い`roots`設定では`src`フォルダを指定します。
* `testMatch`設定は、ts/tsx/jsフォーマットで書かれた.test/.specファイルを発見するためのglobのパターンマッチャーです。
* `transform`設定は、ts/tsxファイルに対して`ts-jest`を使うよう`jest`に指示します。

## 手順3：テストを実行する

あなたのプロジェクトのルートから`npx jest`を実行すると、jestはあなたのテストを実行します。

### オプション：npmスクリプトのスクリプトターゲットを追加する

`package.json`に追加してください：

```javascript
{
  "test": "jest"
}
```

* これにより、簡単な`npm t`でテストを実行できます。
* また、`npm t --watch`のwatchモードでも。

### オプション：watchモードでjestを実行する

* `npx jest --watch`

### 例

* `foo.ts`ファイルの場合：

```javascript
export const sum
  = (...a: number[]) =>
    a.reduce((acc, val) => acc + val, 0);
```

* 単純な`foo.test.ts`：

```javascript
import { sum } from '../foo';

test('basic', () => {
  expect(sum()).toBe(0);
});

test('basic again', () => {
  expect(sum(1, 2)).toBe(3);
});
```

ノート：

* Jestは、グローバルな`test`関数を提供します。
* Jestには、グローバルな`expect`の形でアサーションがあらかじめ組み込まれています。

### Example async

Jestには、async/awaitサポートが組み込まれています。例えば:

```javascript
test('basic', async () => {
  expect(sum()).toBe(0);
});

test('basic again', async () => {
  expect(sum(1, 2)).toBe(3);
}, 1000 /* optional timeout */);
```

### enzymeの例

> [enzyme/Jest/TypeScriptのPro eggheadレッスン](https://egghead.io/lessons/react-test-react-components-and-dom-using-enzyme)

enzymeのDOMサポートは、Reactコンポーネントをテストすることができます。enzymeを設定するには3つのステップがあります：

1. enzyme、enzymeの型、より良いenzymeのスナップショットシリアライザ、あなたのreactバージョンのためのenzyme-adapter-reactをインストールします。`npm i enzyme @types/enzyme enzyme-to-json enzyme-adapter-react-16 -D`
2. `"snapshotSerializers"`と`"setupTestFrameworkScriptFile"`を`jest.config.js`に追加します：

```javascript
module.exports = {
  // OTHER PORTIONS AS MENTIONED BEFORE

  // Setup Enzyme
  "snapshotSerializers": ["enzyme-to-json/serializer"],
  "setupFilesAfterEnv": ["<rootDir>/src/setupEnzyme.ts"],
}
```

1. `src/setupEnzyme.ts`ファイルを作成します。

```javascript
import { configure } from 'enzyme';
import EnzymeAdapter from 'enzyme-adapter-react-16';
configure({ adapter: new EnzymeAdapter() });
```

次に、reactコンポーネントとテストの例を示します:

* `checkboxWithLabel.tsx`：

```typescript
import * as React from 'react';

export class CheckboxWithLabel extends React.Component<{
  labelOn: string,
  labelOff: string
}, {
    isChecked: boolean
  }> {
  constructor(props) {
    super(props);
    this.state = { isChecked: false };
  }

  onChange = () => {
    this.setState({ isChecked: !this.state.isChecked });
  }

  render() {
    return (
      <label>
        <input
          type="checkbox"
          checked={this.state.isChecked}
          onChange={this.onChange}
        />
        {this.state.isChecked ? this.props.labelOn : this.props.labelOff}
      </label>
    );
  }
}
```

* `checkboxWithLabel.test.tsx`：

```typescript
import * as React from 'react';
import { shallow } from 'enzyme';
import { CheckboxWithLabel } from './checkboxWithLabel';

test('CheckboxWithLabel changes the text after click', () => {
  const checkbox = shallow(<CheckboxWithLabel labelOn="On" labelOff="Off" />);

  // Interaction demo
  expect(checkbox.text()).toEqual('Off');
  checkbox.find('input').simulate('change');
  expect(checkbox.text()).toEqual('On');

  // Snapshot demo
  expect(checkbox).toMatchSnapshot();
});
```

## 私たちがjestを好きな理由

> [これらの機能の詳細についてはjest websiteを参照してください](http://facebook.github.io/jest/)

* ビルトインのアサーションライブラリ
* 優れたTypeScriptサポート
* 非常に信頼できるテストwatcher
* スナップショットテスト
* ビルトインのカバレッジレポート
* ビルトインのasync/awaitサポート


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://typescript-jp.gitbook.io/deep-dive/intro-1/jest.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
