1

現在、npm モジュールを同期的loadable.libにロードするために使用されていた約 20 個の新しいファイルに対して、遅延ロードを使用しています。変更はドラフト PR で待機中ですが、渡されたモジュールがロードされるreact-toastifyのを待機しないため、単体テストが壊れているようです。loadable.lib

予想された結果

以前とまったく同じように動作するようにモックできloadable.libますが、指定されたライブラリを同期的にロードします。単体テストでは、loadable.lib結果のコンポーネントの子がそのライブラリにアクセスできるため、最初のレンダリングでこれが正常に実行されます。

実績

古いスナップショット (タグとネストされたものと小道具でいっぱい) と新しいスナップショット ( null) は一致しません。これらは機能しません:

// TODO: not working because loadable is used in many places
// and children are not always enough to render to avoid crashes,
// and even just with children there can be crashes
jest.mock('@loadable/component', (loadfn) => ({
  lib: jest.fn(() => {
    return { toast: {} };
  }),
}));

一部のライブラリがロードされるのを待つ代わりに、関数をモックloadable.libしてその子をレンダリングすることが可能である場合、コードが使用する未定義の変数をどのように埋めることができるかわかりません。の上。

webpackPrefetchやなどの WebPack のヒントがいくつかあることを読みましたがwebpackPreload、それが良い道であるかどうかはわかりません。

私が試したことに関する関連リンク

  1. 私が取り組んでいるコード (そして、このようなファイルが他に 19 個あります): https://github.com/silviubogan/volto/blob/1d015c145e562565ecfa058629ae3d7a9f3e39e4/src/components/manage/Actions/Actions.jsx (現在作業中です)読み込みreact-toastify中はloadable.lib常に。)

  2. https://medium.com/pixel-and-ink/testing-loadable-components-with-jest-97bfeaa6da0b - その記事のコードと同様のことをしようとしましたが、うまくいきません:

jest.mock('@loadable/component', async (loadfn) => {
   const val = await loadfn();
   return {
     lib: () => val,
   };
});

ちょっとしたコード

上記のリンクから取得した、これは私が現在react-toastify(という名前LoadableToast)を使用する方法です:

/**
 * Render method.
 * @method render
 * @returns {string} Markup for the component.
 */
render() {
  return (
    <LoadableToast>
      {({ default: toast }) => {
        this.toast = toast;

        return (
          <Dropdown
            item
            id="toolbar-actions"

結論

言い換えれば、動的インポートをモックするにはどうすればよいですか? テストが値を受け取るのを待たせるのではなく、jest を遅延読み込みに移行させて値を提供するにはどうすればよいですか?

ありがとうございました!

更新 1

次の新しいコードでは、まだ機能していません:

jest.mock('@loadable/component', (load) => {
  return {
    lib: () => {
      let Component;
      const loadPromise = load().then((val) => (Component = val.default));
      const Loadable = (props) => {
        if (!Component) {
          throw new Error(
            'Bundle split module not loaded yet, ensure you beforeAll(() => MyLazyComponent.load()) in your test, import statement: ' +
              load.toString(),
          );
        }
        return <Component {...props} />;
      };
      Loadable.load = () => loadPromise;
      return Loadable;
    },
  };
});
4

2 に答える 2