0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

フロントエンド開発のためのテスト入門のサンプルコードをnextからreact-router-domに置き換えたメモ

Posted at

概要

フロントエンド開発のためのテスト入門 今からでも知っておきたい自動テスト戦略の必須知識サンプルコードをNextではなくReact+react-router-domで書き換えた。

この時点のコード
Storybook

stroybookをv6からv7に。

import { ComponentMeta, ComponentStoryObj } from "@storybook/react";

deprecatedなので下記に修正。

import { Meta, StoryObj } from "@storybook/react";

S3

sdkをv3に。

services/client/UploadImage/type.ts

import type { PresignedPost } from "@aws-sdk/s3-presigned-post";

export type UploadImageData = {
  url: string;
  filename: string;
  fields: PresignedPost["fields"];
};

react-router-dom

nextの使用をやめたので、代わりにnext-router-domを使っている。
書き方はそこそこ異なっている。

import { SelectFilterOption } from "@/components/molecules/SelectFilterOption";
import { parseAsNonEmptyString } from "@/lib/util";
import styles from "./styles.module.css";
import { useNavigate, useSearchParams } from "react-router-dom";

const options = [
  { value: "all", label: "すべて" },
  { value: "public", label: "公開" },
  { value: "private", label: "下書き" },
];

export const Header = () => {
  const navigate = useNavigate();
  const [searchParams] = useSearchParams();
  const defaultValue =
    parseAsNonEmptyString(searchParams.get("status")) || "all";
  return (
    <header className={styles.header}>
      <h2 className={styles.heading}>投稿記事一覧</h2>
      <SelectFilterOption
        title="公開ステータス"
        options={options}
        selectProps={{
          defaultValue,
          onChange: (event) => {
            const status = event.target.value;
            searchParams.set("status", status);
            navigate({
              pathname: `/my/posts`,
              search: searchParams.toString(),
            });
          },
        }}
      />
    </header>
  );
};

jest


test("公開ステータスを変更すると、status が変わる", async () => {
  // すでにある page=1 が消えていないこともあわせて検証
  const router = createMemoryRouter(
    [
      { path: "/my/posts", element: <Header /> }
    ],
    { initialEntries: ["/my/posts?page=1&status=public"] },
  );
  render(<RouterProvider router={router} />);
  const combobox = screen.getByRole("combobox", { name: "公開ステータス" });
  async function selectOption(label: string) {
    await user.selectOptions(combobox, label);
  }
  await waitFor(() => {
    selectOption("公開");
    expect(router.state.location.pathname).toBe(`/my/posts`);
    expect(router.state.location.search).toBe(`?page=1&status=public`);
  });
  await selectOption("下書き");
  await waitFor(() => {
    expect(router.state.location.pathname).toBe(`/my/posts`);
    expect(router.state.location.search).toBe(`?page=1&status=private`);
  });
});

Storybook

+ import { withRouter } from "storybook-addon-react-router-v6";

export default {
  component: Profile,
  args: getMyProfileData,
+   decorators: [withRouter],
} as Meta<typeof Profile>;

type Story = StoryObj<typeof Profile>;

export const Default: Story = {};

svg

webpackからviteに変更しており、SVGを読み込む設定をしていないのでimgとして読み込む必要がある。
これは設定変更だけでできるならならいたい。

import GitHub from "./assets/github.svg";
import Twitter from "./assets/twitter.svg";
import styles from "./styles.module.css";

type Props = {
  githubAccount?: string;
  twitterAccount?: string;
};

export const Accounts = (props: Props) => {
  return (
    <div className={styles.accounts}>
      {props.githubAccount && (
        <p className={styles.github}>
          <a
            href={`https://github.com/${props.githubAccount}`}
            target="_blank"
            rel="noopener noreferrer"
          >
-           <Github />
+            <img src={GitHub} /> <span>{props.githubAccount}</span>
          </a>
        </p>
      )}
      {props.twitterAccount && (
        <p className={styles.twitter}>
          <a
            href={`https://twitter.com/${props.twitterAccount}`}
            target="_blank"
            rel="noopener noreferrer"
          >
-            <Twitter /> <span>{props.twitterAccount}</span>
+            <img src={Twitter} /> <span>{props.twitterAccount}</span>
          </a>
        </p>
      )}
    </div>
  );
};
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?