Testing Libraryでbootstrapをテストする

公開日: 

やりたいこと

Bootstrapでスタイルや挙動を制御しているコンポーネントのユニットテストをTesting Libraryで行いたいです。 具体的にはBootstrapのドロップダウンを利用しているコンポーネントでボタンを押した際に、ボタンのaria-expanded属性が true になっているかのテストをします。

何も考えずにやろうとすると失敗する

以下のように、特に何も考えずにテストをやろうとすると失敗します。 setup関数の中の処理は本筋ではないので説明を省きます。

const setup = (
  Component: typeof Dropdown,
  props?: ComponentPropsWithRef<typeof Dropdown>,
) => {
  const user = userEvent.setup();
  render(<Component {...props} />);

  return {
    user,
  };
};

describe('<Dropdown />', () => {
  it('Button should have right attribute when click', async () => {
    expect.assertions(2);
    const { user } = setup(Dropdown);
    const dropdownButton = screen.getByText('dropdown');

    expect(dropdownButton).toHaveAttribute('aria-expanded', 'false');

    await user.click(dropdownButton);

    expect(dropdownButton).toHaveAttribute('aria-expanded', 'true');
  });
});
Expected the element to have attribute:
  aria-expanded="true"
Received:
  aria-expanded="false"

ボタンをクリックしても、aria-expanded="true"になっていないので、テストが失敗します。

原因

結論から言うと、bootstrapjavascript ファイルが import されていないため、dropdown のボタンが正しく動作していません。

テストではなく、通常のアプリケーションの場合はどこかしらのファイルであらかじめbootstrapの javascript ファイルを読み込んでいると思います。

自分の場合はRemixというフレームワークをしているので、entry.client.tsxというファイルで

import 'bootstrap/dist/js/bootstrap.bundle.min';

上のように javascript ファイルを読み込んでいます。

ただ、テストの場合テスト対象になっているファイル内しか実行されないので、別の部分で import されている javascript ファイルは動作に含まれません。

なので、テストファイル内で明示的に javascript ファイルを読み込んであげる必要があります。

解決策

import 'bootstrap/dist/js/bootstrap.bundle.min';

テストファイル内で上のようにbootstrapの javascript ファイルを import しましょう。

これでドロップダウンボタンを押した時に javascript の処理が走り、正常に attribute がセットされます。

最後に

フロントのテストを完全に理解しているわけではないのでどんなテストが必要なのかを考えるのが難しい。

では

Bye