#1 Jestのチュートリアルをやってみる

# はじめに
業務でJestが採用されたこともあり、公式のチュートリアルを実践してみる。
とりあえずTypeScriptが実行できるところまでをやっていく。

# 実践

## チュートリアル
公式のチュートリアルは、以下のURLから。
ざっと見た感じreactのチュートリアルほどは体系的にはなっていない印象。
必要なものをかいつまんで実施。

https://jestjs.io/ja/docs/getting-started

# インストール
node、npmは、インストール済みの環境で実施。
なにはともあれJestのインストール。

```
npm install --save-dev jest
```

# テスト対象作成

まずはjavascriptのテストからやってみる。テスト対象のコードは、チュートリアルからそのまま拝借。
```javascript:sum.js
function sum(a, b) {
  return a + b;
}
module.exports = sum;
```

# テストコード作成

テストコードもそのまま。
```javascript:sum.test.js
const sum = require('./sum');

test('adds 1 + 2 to equal 3', () => {
  expect(sum(1, 2)).toBe(3);
});
```

# package.json にnpmスクリプトを追加

```json:package.json
{
  "devDependencies": {
    "jest": "^29.7.0"
  },
  "scripts": {
    "test": "jest"
  }
}
```

# テスト実行
実行してみる。

```
npm run test
```

テスト成功。
```console
PS C:\GitHub\Jest1> npm run test
> test
> jest

 PASS  ./sum.test.js
  √ adds 1 + 2 to equal 3 (1 ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        1.09 s
Ran all test suites.
```

# コマンドラインからの実行
CLIからの実行は今回実施しないのでスキップ。

# 追加設定

以下のコマンドで、プロジェクト構成に基づいた基本の設定ファイルを作成してくれるとのこと。今回はなぜかうまく使えなかったのでスキップ。気が向いたら別途調査する。

```
npm init jest@latest
```

# Babelインストール

JestはBabel経由でTypeScriptをサポートしているとのことなので、インストールする。

```
npm install --save-dev babel-jest @babel/core @babel/preset-env
```

# 設定ファイルを作成
プロジェクトのルートにbabel.config.jsファイルを作成し、以下を追記。
Babelのトランスパイルのターゲットに現在のnodeのバージョンを指定。

```javascript:babel.config.js
module.exports = {
  presets: [['@babel/preset-env', {targets: {node: 'current'}}]],
};
```

# Webpackを使用する
今回は実施しないのでスキップ。

# Viteを使用する
今回は実施しないのでスキップ。

# Parcelを使用する
今回は実施しないのでスキップ。


# BabelのTypeScriptプリセットのインストール
BabelでTypeScriptコードをトランスパイルできるようにするプリセットをインストールする。

```
npm install --save-dev @babel/preset-typescript
```

# Babelの設定ファイルを編集

```javascript:babel.config.js
module.exports = {
  presets: [
    ['@babel/preset-env', {targets: {node: 'current'}}],
    '@babel/preset-typescript',
  ],
};
```

# ts-jest インストール

TypeScriptのコードがテストできるようにts-jestをインストールする。

```
npm install --save-dev ts-jest
```

# ts-jest の設定ファイルを作成

```
npx ts-jest config:init
```

```typescript:jest-config.ts
/** @type {import('ts-jest').JestConfigWithTsJest} */
module.exports = {
  preset: 'ts-jest',
  testEnvironment: 'node',
};
```

# @jest/globals をインストール


Jestのグローバルな関数、オブジェクトは通常importなしで使用できるが、明示的にimport文で指定したい場合に@jest/globalsを使用する、という理解。

```
npm install --save-dev @jest/globals
```

# テストコードを書き換える

```typescript:sum.test.ts
import {describe, expect, test} from '@jest/globals';
import sum from './sum';

describe('sum module', () => {
  test('adds 1 + 2 to equal 3', () => {
    expect(sum(1, 2)).toBe(3);
  });
});
```

# テスト対象のコードをTypeScriptで書き換える

```typescript:sum.ts
const sum = (a: number, b: number) :number => {
    return a + b;
  }
export default sum;
```

# テスト実行

```
npm run test
```

テスト成功。

```console
PS C:\GitHub\Jest1> npm run test 

> test
> jest

ts-jest[config] (WARN) message TS151001: If you have issues related to imports, you should consider setting `esModuleInterop` to `true` in your TypeScript configuration file (usually `tsconfig.json`). See https://blogs.msdn.microsoft.com/typescript/2018/01/31/announcing-typescript-2-7/#easier-ecmascript-module-interoperability for more information.
 PASS  ./sum.test.ts
  sum module
    √ adds 1 + 2 to equal 3 (2 ms)                                                              
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total                                                                  Snapshots:   0 total
Time:        1.273 s, estimated 3 s
Ran all test suites.
```

tsconfig.jsonのesModuleInteropというオプションをtrueにするよう警告がでています。tsconfig.jsonファイルを作成していなかったので作成します。

# tsconfig.json を作成
```
npx tsc --init
```
esModuleInteropはデフォルトでtrueになりました。

# テスト実行
再度テストを実行します。
```
npm run test
```

テスト成功。警告も消えました。

```console
PS C:\GitHub\Jest1> npm run test  

> test
> jest

 PASS  ./sum.test.ts
  sum module
    √ adds 1 + 2 to equal 3 (2 ms)
Test Suites: 1 passed, 1 total                                                                  
Tests:       1 passed, 1 total                                                                  Snapshots:   0 total
Time:        2.564 s
Ran all test suites.