ホームページ  >  に質問  >  本文

Jest を使用して React BooksContainer 単体テストに GetBooksAction のモックを追加するにはどうすればよいですか?

私は React と Jest を初めて使用するため、これまでのところほとんどすべてのことに苦労しています。見つけたチュートリアルに従おうとしています。

これは、シンプルなブックストア React フロントエンド アプリケーションです。ここまでは、単純なレイアウト コンポーネントを作成し、次に取得した本のリストを含む BookContainer コンポーネント内に BookList コンポーネントを作成しました。次に、各書籍には BookListItem コンポーネントがあります。

次に、バックエンドの Rest API から書籍を取得するための単純な BookService と getAllBooks を用意します。さらに、Redux ストアへの保存とそこからの取得をすべて処理する単純な BookReducer、BookSelector、BookAction があります。

redux、react-hooks、redux ツールキット、jest、JavaScript を使用しています。

これを Web ブラウザで実行すると、すべてが正常に動作し、書籍が取得されてストアに保存され、BookContainer コンポーネントでレンダリングされます。

今、この BookContainer コンポーネントに簡単な単体テストを追加しようとしており、ヘルプを探しています。

この単体テストでは、BookList コンポーネントがレンダリングされたかどうか (haveBeenCalledWith)、つまり render メソッドに渡した書籍のリストをチェックしたいと考えています。

また、レンダリングに渡す書籍のリストを返す BookAction をモックしたいと考えています。まさにこれが私が今取り組んでいることです。

これは私の BookContainer コンポーネントです:

リーリー

これは私の BookList コンポーネントです:

リーリー

これは私の BookAction です:

リーリー

これは私の BookContainer.test.jsx です:

リーリー

これは、テストで使用する bookContainerStateWithData の TestDataProvider です:

リーリー

これは、テストで使用する TestSetupProvider の renderWithRedux() ヘルパー メソッドです:

リーリー

これは、TestSetupProvider で使用される createSoteWithMiddleware() を提供する私の ReduxStoreHelper です:

リーリー

および現在受信しているエラー メッセージ:

リーリー

BookContainer 単体テストのこの行:

リーリー

助けやアドバイスをありがとうございます。同様の問題と解決策を探してきましたが、これまでのところ成功していません。

編集1

getBooksAction のジョーク モックに __esModule: true を次のように追加すると:

リーリー

その場合、エラー メッセージは異なります:

リーリー

編集2

getBooksAction キーを次のようにジョーク シミュレーションのデフォルトに変更すると:

リーリー

この場合、型エラーはなくなりましたが、アサーション エラーが発生しました (もう少し近いものになります):

リーリー

したがって、空の書籍配列が返されるようになりました。では、与えられた書籍の配列を発送するようにシミュレーションを変更するにはどうすればよいでしょうか?

編集 3

問題の根本原因が見つかったと思います。 BookContainer が作成されてレンダリングされると、書籍が連続して複数回フェッチされます。最初の 2 つは空の書籍配列を返します。 3回目以降は取得したbooks配列を返却します。これは、 useEffect の後に BookContainer にコンソール ログを追加することでわかります:

リーリー

連続で何度も呼び出す必要がありますか?書籍の配列を正しく取得するには、1 回の呼び出しだけでよいのではないでしょうか?この動作の原因は何ですか。コードのどこかに問題があるのでしょうか?

ちなみに、これが BookContainer コンポーネントにこの迷惑な IF ステートメントがある理由でもあります。チュートリアルには記載されていませんが、すべてが期待どおりに機能します。 BookContainer がレンダリングされるたびに、リクエスト/操作が 2 倍になるようです...

編集4

インデックス ファイルで StrictMode を使用しました。これを削除した後、二重リクエストはなくなり、BookContainer の useEffect() は 1 回だけ実行されるようになりました。ただし、BookContainer の render メソッドは依然として 2 回実行されます。1 回目は空のブック配列で、2 回目はフェッチされたブック配列で実行されます。

P粉463291248P粉463291248208日前389

全員に返信(1)返信します

  • P粉986028039

    P粉9860280392024-02-27 00:23:34

    最終的な根本原因は、バックエンドとフロントエンドの間の応答データのマッピングが間違っていたことでした。

    get book エンドポイントに対する私の API 応答は次のとおりです:

    {
        「本」: [...]
    }

    つまり、基本的には json 配列ではなく、内部に配列を含む json オブジェクトです。 API 応答の優れた実践例にあるように、より柔軟になる必要があります。

    ただし、私のフロントエンドでは、私が書いたコードは基本的に、API 応答が BookList 内の単なる json 配列であると誤って想定しています。

    const propTypes = { 本: Proptypes.arrayOf( Proptypes.shape({ id: Proptypes.number.isRequired、 タイトル: Proptypes.string.isRequired、 説明: Proptypes.string.isRequired、 著者: Proptypes.string.isRequired、 release Year: Proptypes.number.isRequired、 }) )。が必要です、 };
    次のように変更します: 

    const propTypes = { BooksResponse: Proptypes.shape({ 本: Proptypes.arrayOf( Proptypes.shape({ id: Proptypes.number.isRequired、 タイトル: Proptypes.string.isRequired、 説明: Proptypes.string.isRequired、 著者: Proptypes.string.isRequired、 release Year: Proptypes.number.isRequired、 }) )。が必要です、 }) };
    次に、この変更を BookList コンポーネントにさらに適用します: 

    const BookList = ({booksResponse}) => { 戻る ( <ボックスクラス名={styles.bookList} ml={5}> {booksResponse.books.map((本) => { 戻る ( <BookListItem book={book} key={book.id} /> ); })} </ボックス> ); }
     最後に単体テストでも: 

    expect(BookList).toHaveBeenLastCalledWith({booksResponse:books }, {});
     そして、getBooksAction モックにはデフォルトや __esModule は必要ありません: 

    jest.mock("../../../modules/book/BookAction", () => ({ getBooksAction: jest.fn()、 }));
     すべてが期待どおりに機能します。 :)

    返事
    0
  • キャンセル返事