AngularでJestを使えるようにする

# はじめに
最近React触るついでにJestをやってみたところ非常に快適だったためAngularでもやってみる。
とりあえず動くとこまで試してみる。

# TL;DR.
[ソースコード](https://github.com/Tetsuya-Minase/program-samples/tree/master/ng-jest)

# セットアップ
いつも通りプロジェクトを作るとこから……の前に[必要なパッケージ](https://github.com/briebug/jest-schematic)をインストールしておく。
セットアップは下記で完了。

``` sh
$ npm install -g @briebug/jest-schematic
# あとはいつも通りプロジェクトを作って
$ ng new ng-jest
> 聞かれるのはお好みで
$ cd ng-jest
# さっきインストールしたパッケージを使ってjestに変える
$ ng g @briebug/jest-schematic:add
$ ng add @briebug/jest-schematic
> karma用のファイルが削除され、jest用のファイルが作成される
```

# tsconfig.spec.jsonの修正
typesにある`jasmine`を`Jest`に変更。
変更しなくても一応動くっぽい。

```json
...
"types": [
    "jest",
    "node"
],
...
```

# 動かしてみる
ここまでやれば`npm test`で`jest`を使ったテストが走るようになる。

```sh
$ npm test
> > ng-jest@0.0.0 test .../ng-jest
> > jest
>  PASS  src/app/app.component.spec.ts
>  AppComponent
>     ✓ should create the app (132ms)
>     ✓ should have as title 'ng-jest' (30ms)
>     ✓ should render title in a h1 tag (28ms)
> Test Suites: 1 passed, 1 total
> Tests:       3 passed, 3 total
> Snapshots:   0 total
> Time:        2.808s, estimated 5s
> Ran all test suites.
```
ちなみに`ng test`では動かない。
デフォでは`karma`を使おうとして失敗する。

```sh
$ ng test
> An unhandled exception occurred: Cannot find module 'karma'
> Require stack:
> ...
```

## おまけ：どうしても`ng test`で動かしたい場合
パッケージのインストールと`angular.json`の修正が必要。
インストールと`angular.json`の修正は下記の通り。

```sh
# @types/jestはなくても可
$ npm i -D jest @angular-builders/jest  @types/jest

...
"test": {
    // @angular-devkit/build-angular:karmaを下記に変更
    "builder": "@angular-builders/jest:run",
...
```

# snapshotテストをやってみる
`Jest`使うのでせっかくだからsnapshotテストもやってみる。
とりあえずsnapshotテストの項目を追加して実行してみる。

```typescript
it('snapshot test', () => {
    const fixture = TestBed.createComponent(AppComponent);
    fixture.detectChanges();
    const compiled = fixture.debugElement.nativeElement;
    expect(compiled).toMatchSnapshot();
});
```

`__snapshots__`フォルダに`app.component.spec.ts.snap`というファイルができていればOK。
ファイルの中身は下記の通り。

```
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`AppComponent snapshot test 1`] = `
<div
  id="root3"
  ng-version="8.2.9"
>
  <div
    style="text-align:center"
  >
    <h1>
       Welcome to ng-jest! 
    </h1>
    <img
      alt="Angular Logo"
      src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTAgMjUwIj4KICAgIDxwYXRoIGZpbGw9IiNERDAwMzEiIGQ9Ik0xMjUgMzBMMzEuOSA2My4ybDE0LjIgMTIzLjFMMTI1IDIzMGw3OC45LTQzLjcgMTQuMi0xMjMuMXoiIC8+CiAgICA8cGF0aCBmaWxsPSIjQzMwMDJGIiBkPSJNMTI1IDMwdjIyLjItLjFWMjMwbDc4LjktNDMuNyAxNC4yLTEyMy4xTDEyNSAzMHoiIC8+CiAgICA8cGF0aCAgZmlsbD0iI0ZGRkZGRiIgZD0iTTEyNSA1Mi4xTDY2LjggMTgyLjZoMjEuN2wxMS43LTI5LjJoNDkuNGwxMS43IDI5LjJIMTgzTDEyNSA1Mi4xem0xNyA4My4zaC0zNGwxNy00MC45IDE3IDQwLjl6IiAvPgogIDwvc3ZnPg=="
      width="300"
    />
  </div>
  <h2>
    Here are some links to help you start: 
  </h2>
  <ul>
    <li>
      <h2>
        <a
          href="https://angular.io/tutorial"
          rel="noopener"
          target="_blank"
        >
          Tour of Heroes
        </a>
      </h2>
    </li>
    <li>
      <h2>
        <a
          href="https://angular.io/cli"
          rel="noopener"
          target="_blank"
        >
          CLI Documentation
        </a>
      </h2>
    </li>
    <li>
      <h2>
        <a
          href="https://blog.angular.io/"
          rel="noopener"
          target="_blank"
        >
          Angular blog
        </a>
      </h2>
    </li>
  </ul>
</div>
`;
```

## テストに失敗する or テストコードの警告を消したい場合
`import 'jest'`を追記すればOK.
ちゃんとした解決法じゃないのかもしれないけど、一旦これで解決できるので良しとする。

# まとめ
AngularでJestを使えるようにした。
snapshotもできるしメッセージもわかりやすい(と思っている)ので、
これからはJestを使っていきたいところ。
それでは今回はこの辺で。

# 参考にしたサイト
- [【超簡単】AngularでFacebook製のJSテストフレームワーク「Jest」を使えるようにしてみる](https://dev.classmethod.jp/client-side/angular-jest-setup/)
- [既存のAngularプロジェクトにJestを導入する方法](https://qiita.com/rena_m/items/42e7eede8f6cd411f111)
- [AngularのテスティングフレームワークにJestを利用する](https://blog.yuhiisk.com/archive/2019/05/07/angular-test-with-jest.html)