shunnami
@shunnami (miffiy)

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

【React Testing Library】非同期の処理をawaitで待った後に、queryByTextでテストしたい。

解決したいこと

React testing LibraryとJestをつかってAppコンポーネントのテストをコードを書いています。
テストはパスできるのですが、非同期の処理が完了するのを待つために必要ないawait findByRoleを書いています。
必要のない記述をなくして、非同期の処理の完了を待つ方法をご教示いただきたいです。

テストコード

  test("通信失敗時に「成功!」が画面に表示されないこと",  async() => {
    render(<App/>);

// 関数Aをモック化(ここでは、getUserNameApiを関数Aとします)
    getUserNameApiMock.mockResolvedValue(apiResult);

// 関数Aの戻り値
    apiResult.result = false;
    apiResult.userName="mockName";
 2   apiResult.message="mockMessage"

// 関数Aの実行前に成功!の文字がないことを確認
    expect(screen.queryByText(/成功!/i)).toBeNull()

// ボタンをクリック
//(このボタンが押されたとき、関数Aが動きます。関数Aの戻り値であるresultがfalseなら画面に完了!の文字は出ません。falseが帰るように設定しています)
    userEvent.click(screen.getByRole('button'));
// ★問題としている必要のない記述です。これを無くしたい!
    await screen.findByRole("button");

// 関数Aの実行結果がfalseのときは画面に成功!が表示されないことをテスト
    expect(screen.queryByText(/成功!/i)).toBeNull()

  })

自分で試したこと

(1). screen.queryByTextをawaitで待つ

queryByTextはawatiで待てないので、失敗。

(2). findの結果を変数に格納してからテストする

    const message = await screen.findByText("成功!");
    expect(message).toBeNull();

1行目でfindByTextがエラーになるため、失敗。findByTextは見つからない場合はエラーを返すためだと思われる。

(3) expect(screen.findByRole(/成功!/i)).notを試す
(2)と同様エラーが返るため失敗。

0

1Answer

詳しくないので、記事の紹介になりますが……
queryBy*, getBy*はwaitForでラップしてawaitするのが一般的なようです。

userEventをawaitしている例もありますが、実際どうかは未確認です。

1Like

Comments

  1. @shunnami

    Questioner

    ご回答ありがとうございます。
    やりたいことができました。

Your answer might help someone💌