Vue.js+TypeScript (Vue.ts) へ、Vue Test Utils+Jestを入れた際に発生したエラーを解消した軌跡

# Vue.jsでTypeScriptと一緒にVue Test Utils+Jestを使う

公式の日本語ドキュメントの

- [TypeScript と一緒に使う | Vue Test Utils](https://vue-test-utils.vuejs.org/ja/guides/using-with-typescript.html)

に記載されている手順通り順番に導入していくと案外すんなりといかなかったので、その際に試した解決方法をここに残しておきます。
（ちなみに上から順番に解決していったのでもしかしたら**余計なプラグインが入っているかもしれません**）

なおここで扱う**テストコード（`HelloWorld.spec.ts`）**と**テスト対象のコード（`HelloWorld.vue`）**は**[公式のリポジトリにあるコード](https://github.com/vuejs/vue-test-utils-typescript-example)**と同じ想定です。

<details><summary>**src\components\HelloWorld.vue**</summary><div>

```src\components\HelloWorld.vue
<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
    <p>
      For guide and recipes on how to configure / customize this project,<br>
      check out the
      <a href="https://cli.vuejs.org" target="_blank">vue-cli documentation</a>.
    </p>
    <h3>Installed CLI Plugins</h3>
    <ul>
      <li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-typescript" target="_blank">typescript</a></li>
    </ul>
    <h3>Essential Links</h3>
    <ul>
      <li><a href="https://vuejs.org" target="_blank">Core Docs</a></li>
      <li><a href="https://forum.vuejs.org" target="_blank">Forum</a></li>
      <li><a href="https://chat.vuejs.org" target="_blank">Community Chat</a></li>
      <li><a href="https://twitter.com/vuejs" target="_blank">Twitter</a></li>
      <li><a href="https://news.vuejs.org" target="_blank">News</a></li>
    </ul>
    <h3>Ecosystem</h3>
    <ul>
      <li><a href="https://router.vuejs.org" target="_blank">vue-router</a></li>
      <li><a href="https://vuex.vuejs.org" target="_blank">vuex</a></li>
      <li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank">vue-devtools</a></li>
      <li><a href="https://vue-loader.vuejs.org" target="_blank">vue-loader</a></li>
      <li><a href="https://github.com/vuejs/awesome-vue" target="_blank">awesome-vue</a></li>
    </ul>
  </div>
</template>

<script lang="ts">
import Vue from 'vue';
export default Vue.extend({
  name: 'HelloWorld',
  props: {
    msg: String,
  },
});
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h3 {
  margin: 40px 0 0;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  display: inline-block;
  margin: 0 10px;
}
a {
  color: #42b983;
}
</style>
```

</div></details>

<details><summary>**src\components\__tests__\HelloWorld.spec.ts**</summary><div>

```src\components\__tests__\HelloWorld.spec.ts
import 'jest';
import { shallowMount } from '@vue/test-utils'
import HelloWorld from '../HelloWorld.vue'

describe('HelloWorld.vue', () => {
  test('renders props.msg when passed', () => {
    const msg = 'new message'
    const wrapper = shallowMount(HelloWorld, {
      propsData: { msg }
    })
    expect(wrapper.text()).toMatch(msg)
  })
})
```

</div></details>

# ①、VSCode上で`Cannot find name 'describe'.`と警告される

Visual Studio Codeでテストコードを記述した際に以下のように警告されました

```
Cannot find name 'describe'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig.ts(2593)
```

## ①解決方法

`jest`をインストールし、`tsconfig.json`に以下の記述を追加

```tsconfig.json
{
  "compilerOptions": {
    // ..
    "types": [
      "webpack-env",
      "jest" // typesにjestを追加
    ],
    // ..
}
```

# ②、テスト実行時に`spawn jest ENOENT`というエラーが発生

①を解消後、テストを実行すると以下のエラーが発生。

```console
Error while running task C:\work\project\vue:test:unit with message 'spawn jest ENOENT'
```

（VueUIでのエラーログ）

![FireShot Capture 007 - [Beta] test_unit - プロジェクトタスク - Vue CLI - localhost.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85815/93f1d4a4-66a4-3106-c567-b67831aa58ec.png)

以下詳細なエラー

```
Error: spawn jest ENOENT
    at notFoundError (C:\Users\sola\AppData\Roaming\npm\node_modules\@vue\cli\node_modules\cross-spawn\lib\enoent.js:6:26)
    at verifyENOENT (C:\Users\sola\AppData\Roaming\npm\node_modules\@vue\cli\node_modules\cross-spawn\lib\enoent.js:40:16)
    at ChildProcess.cp.emit (C:\Users\sola\AppData\Roaming\npm\node_modules\@vue\cli\node_modules\cross-spawn\lib\enoent.js:27:25)
    at Process.ChildProcess._handle.onexit (internal/child_process.js:272:12) {
  code: 'ENOENT',
  errno: 'ENOENT',
  syscall: 'spawn jest',
  path: 'jest',
  spawnargs: []
}
```

## ②解決方法

グローバルに`jest`と`ts-jest`をインストール

```console
npm i jest ts-jest -g
```

`i` ・・・`install`の省略記法

以下実行結果例

```console
C:\Users\sola>npm i jest ts-jest -g
npm WARN deprecated left-pad@1.3.0: use String.prototype.padStart()

// 略

+ ts-jest@24.1.0
+ jest@24.9.0
added 476 packages from 358 contributors in 19.261s
```

# ③、テスト実行時に`Cannot find module 'babel-core'`とエラーが発生

②を解消後、再度テストを実行。以下のように別エラーが発生

```console
Cannot find module 'babel-core'
```

![FireShot Capture 009 - [Beta] test_unit - プロジェクトタスク - Vue CLI - localhost.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85815/28c55e62-163e-2df6-61af-db4c7fdf6c53.png)


## ③解決方法

プラグイン`babel-core`をインストールする **※**

```
npm i babel-core
```

プラグイン詳細：https://www.npmjs.com/package/babel-core

**※しかしながらこの際、`babel-core`の最新（安定）版をインストールすると以下のエラーが発生しました。**

```
Plugin 1 specified in "C:\\work\\project\\vue\\node_modules\\@vue\\cli-plugin-babel\\preset.js" provided an invalid property of "default" (While processing preset: "C:\\work\\project\\vue\\node_modules\\@vue\\cli-plugin-babel\\preset.js")
```


調べてみるとどうやら**バージョン`7.0.0-bridge.0`を固定して入れるとエラーが解消される**みたいなので、
もし上記のエラーが発生した場合はバージョンを以下のように固定して再インストールしたほうがいいのかもしれません。


```package.json
{
  "dependencies": {
    "babel-core": "7.0.0-bridge.0",
  },
}
```

参考：[Cannot find module 'babel-core' · Issue #4891 · facebook/jest](https://github.com/facebook/jest/issues/4891#issuecomment-452335622)

# おわり

- フロントエンド初心者なんでなにか間違いありましたら指摘ください

# 参考URL
- [typescript - Cannot find name 'describe'. Do you need to install type definitions for a test runner? - Stack Overflow](https://stackoverflow.com/questions/54139158/cannot-find-name-describe-do-you-need-to-install-type-definitions-for-a-test)
- [Exception raised: Process failed: spawn node_modules\.bin\jest.cmd ENOENT · Issue #98 · jest-community/vscode-jest](https://github.com/jest-community/vscode-jest/issues/98)
- [Cannot find module 'babel-core' · Issue #4891 · facebook/jest](https://github.com/facebook/jest/issues/4891#issuecomment-452335622)