reactアプリでのテストコード作成の忘備録(設定)

# 概要
reactアプリでテストコードを作成する際に詰まったエラーの対処方法
[前回](https://qiita.com/kubota_ndatacom/items/c6d821f8f0b310276005)

# 目次
[1. 外部ライブラリをimportした際にUnexpected token 'export'が出た際の対処](#1-外部ライブラリをimportした際にunexpected-token-exportが出た際の対処)
[2. cssファイルをimportしているとエラーになる際の対処](#2-cssファイルをimportしているとエラーになる際の対処)
[3. Testing libraryの拡張マッチャーを使用する](#3-testing-libraryの拡張マッチャーを使用する)

# 1. 外部ライブラリをimportした際にUnexpected token 'export'が出た際の対処
ESModule(import/export)で提供されているパッケージをimportしようとするとエラーになるので
babelを使用してCommonJS形式(module.export/require(“))にトランスコンパイルする
※ビルドは通るがjestでテストを実行しようとするとエラーになる

```
    SyntaxError: Unexpected token 'export'

      3 | import { useHistory,useLocation } from 'react-router-dom';
      4 | import { Container, Draggable } from 'react-smooth-dnd';
    > 5 | import { arrayMoveImmutable } from 'array-move';
        | ^
      6 | import classNames from 'classnames';
      7 | import ReactModal from 'react-modal';
      8 | import { Tab, Tabs, TabList, TabPanel } from 'react-tabs';

      at Runtime.createScriptFromCode (node_modules/jest-runtime/build/index.js:1350:14)
      at Object.<anonymous> (src/Main.js:5:1)
```

babel関係のライブラリをインストール
```
$ npm install babel-jest @babel/core @babel/plugin-transform-modules-commonjs @babel/preset-env
```

pakege.jsonにjestの設定を追記する
"transform"の項でbabel-jestを適用するファイルを指定(例はjsファイル、jsxファイル、mjsファイル)
"transformIgnorePatterns"でトランスコンパイルをするモジュールを指定する(上記エラーでarray-moveがexportを使用しているとの事なのでarray-moveを指定)
※複数指定する場合は"/node_modules/(?!(jest-)?@react-native|array-move)"のように記述する

```diff_json:package.json
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
-    "test": "react-scripts test",
+    "test": "jest",
    "eject": "react-scripts eject"
  },
・・・
  },
+  "jest": {
+    "transform": {
+      "^.+\\.(js|jsx|mjs)$": "babel-jest"
+    },
+    "transformIgnorePatterns": [
+      "/node_modules/(?!(jest-)?array-move)"
+    ]
+  }
```

# 2. cssファイルをimportしているとエラーになる際の対処

cssファイルをimportしてスタイルを適応させているファイルをテストしようとするとエラーになるので
identity-obj-proxyを使ってcssの呼び出し部分をモックする

```
    SyntaxError: Unexpected token '.'

    > 1 | import './common.css';
        | ^
      2 | import React,{ useState,useEffect,Component } from 'react';
      3 | import { useHistory,useLocation } from 'react-router-dom';
      4 | import { Container, Draggable } from 'react-smooth-dnd';

      at Runtime.createScriptFromCode (node_modules/jest-runtime/build/index.js:1350:14)
      at Object.<anonymous> (src/Main.js:1:1)
      at Object.<anonymous> (src/__tests__/UserEdit.test.js:6:1)
```


identity-obj-proxyをインストール
```
$ npm install identity-obj-proxy
```

jestの設定に記述を追記する(cssファイルとlessファイルがidentity-obj-proxyの対象)

```diff_json:package.json
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "jest",
    "eject": "react-scripts eject"
  },
・・・
  },
  "jest": {
    "transform": {
      "^.+\\.(js|jsx|mjs)$": "babel-jest"
    },
    "transformIgnorePatterns": [
      "/node_modules/(?!(jest-)?@react-native|array-move)"
    ],
+    "moduleNameMapper": {
+      "\\.(css|less)$": "identity-obj-proxy"
+    }
  }
```

# 3. Testing libraryの拡張マッチャーを使用する

jest-dom のカスタムマッチャー(toBeInTheDocument等)を使用する際の下記記述を省略する方法

```javascript:App.test.js
import '@testing-library/jest-dom/extend-expect';
```

jestの設定に下記記述を加えるとimport文を書かずに使用出来るようになる

```diff_json:package.json
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "jest",
    "eject": "react-scripts eject"
  },
・・・
  },
  "jest": {
    "transform": {
      "^.+\\.(js|jsx|mjs)$": "babel-jest"
    },
    "transformIgnorePatterns": [
      "/node_modules/(?!(jest-)?@react-native|array-move)"
    ],
    "moduleNameMapper": {
      "\\.(css|less)$": "identity-obj-proxy"
    },
+    "setupFilesAfterEnv": [
+       "@testing-library/jest-dom/extend-expect"
+    ]
  }
```