jestで非同期のテストを行う

## はじめに
Jestを用いて非同期で表示するテーブル一覧の値を取得するテストを作成したところ、時間がかかったのでまとめます。

## エラー内容１
以下のように、モックを作って`findeByText`でテストを実行したところ、エラーが発生しました。
```typescript:AppComponent.spec.tsx : 失敗例
describe('list', () => {
  beforeEach(() => {
    // モックを作成
    const mockFn = jest.spyOn(recordLib, 'GetAllRecords').mockResolvedValue([
      {
        id: '1',
        learn_title: 'おはようございます',
        learn_time: 6,
        created_at: '2024-12-14 22:36:56',
      },
    ]);
  });

  afterEach(() => {
    jest.restoreAllMocks();
  });

  it('一覧を確認することができる', async () => {
    render(<App />);
    // レコードが表示されるのを待つ
    await waitFor(() => {
      const element_str = screen.findByText('おはようございます');
      const element_time = screen.findByText('6');
      const element_ts = screen.findByText('2024-12-14 22:36:56');
      expect(element_str).toBeInTheDocument();
      expect(element_time).toBeInTheDocument();
      expect(element_ts).toBeInTheDocument();
    });
  });
});
```

<details><summary>エラー文１</summary>

```terminal:ターミナル
● list › 一覧を確認することができる

    expect(received).toBeInTheDocument()

    received value must be an HTMLElement or an SVGElement.
    Received has type:  object
    Received has value: {}

    Ignored nodes: comments, script, style
    <html>
      <head />
      <body>
        <div />
      </body>
    </html>

      55 |       const element_time = screen.findByText('6');
      56 |       const element_ts = screen.findByText('2024-12-14 22:36:56');
    > 57 |       expect(element_str).toBeInTheDocument();
         |                           ^
      58 |       expect(element_time).toBeInTheDocument();
      59 |       expect(element_ts).toBeInTheDocument();
      60 |     });

```
</details>

## エラー内容２
`findByText`を`queryByText`に修正しました。
しかし、また別のエラーが発生しました。

```typescript:AppComponent.spec.tsx : 失敗例
describe('list', () => {
  // 一部省略
  
  it('一覧を確認することができる', async () => {
    render(<App />);
    // レコードが表示されるのを待つ
    await waitFor(() => {
      const element_str = screen.findByText('おはようございます');
      const element_time = screen.findByText('6');
      const element_ts = screen.findByText('2024-12-14 22:36:56');
      expect(element_str).toBeInTheDocument();
      expect(element_time).toBeInTheDocument();
      expect(element_ts).toBeInTheDocument();
    });
  });
});
```

<details><summary>エラー文２</summary>

```terminal:ターミナル
● list › 一覧を確認することができる

    ContextError: useContext returned `undefined`. Seems you forgot to wrap component within <ChakraProvider />
```
</details>

## 解決策
`ChakraProvider`をインポートすることで、エラーが解消されました。
```typescript:AppComponent.spec.tsx : 成功例
import { ChakraProvider, defaultSystem } from '@chakra-ui/react';

describe('list', () => {
  // 一部省略

  it('一覧を確認することができる', async () => {
    render(
      <ChakraProvider value={defaultSystem}>
        <App />
      </ChakraProvider>
    );
    // レコードが表示されるのを待つ
    await waitFor(() => {
      const element_str = screen.queryByText('おはようございます');
      const element_time = screen.queryByText('6');
      const element_ts = screen.queryByText('2024-12-14 22:36:56');
      expect(element_str).toBeInTheDocument();
      expect(element_time).toBeInTheDocument();
      expect(element_ts).toBeInTheDocument();
    });
  });
});


```
## 最後に
非同期のテストを行うときは`findBy`を使うと思っていたので、`queryBy`で動作するのは予想外でした。