reactjs Vitest React -服务器请求后组件未“重新渲染”

w51jfk4q  于 2023-03-01  发布在  React
关注(0)|答案(3)|浏览(157)

bounty将在3小时后过期。回答此问题可获得+450声望奖励。djechlin希望引起更多人关注此问题。

这是我的simplifiedReact组件:

export const EntryDetail = () => {
  const { articleId } = useParams();
  const [article, setArticle] = useState({ title: null, body: null, comments: [], likes: [] });
  const { title, body, comments, likes } = article;

  useEffect(() => {
    (async () => {
      try {
        const response = await getArticleDetail(articleId);
        const { title, body, comments, likes } = response.data;
        setArticle({ title, body, comments, likes });
      } catch (e) {
        console.error(e);
      }
    })();
  }, []);

  return (
    <Container>
      {
        !article.title
          ? <div>Loading...</div>
          : <>
            <h1>{title}</h1>
            <p className="body">{body}</p>
          </>
      }

    </Container>
  );
};

这是我的考验

import { render, screen } from '@testing-library/react';
import { StateProvider } from '../../config/state';
import { EntryDetail } from './index';

const flushPromises = () => new Promise(resolve => setTimeout(resolve, 0));

vi.mock('react-router-dom', () => ({
  useParams: () => ({
    articleId: '63d466ca3d00b50db15aed93',
  }),
}));

describe("EntryDetail component", () => {
  it("should render the EntryDetail component correctly", async () => {
    render(
      <EntryDetail />
    );
    await flushPromises();
    const element = screen.getByRole("heading");
    expect(element).toBeInTheDocument();
  });
});

这是我在控制台上看到的:

我原本以为“await flushPromises()”实际上会等待useEffect中调用的响应来“更新”组件”,但我猜这是一种“静态”?这应该如何处理?我实际上想测试组件本身是否有效工作,我不想模拟响应,我想看看组件在响应返回后是否真正做出了适当的React。

bvn4nwqk

bvn4nwqk1#

完全按照https://github.com/vitest-dev/vitest/tree/main/examples/react-testing-lib中的示例操作。确保vite.config.jssetup.ts中没有丢失config。

aij0ehis

aij0ehis2#

您可以按照以下simplifiedReact组件示例进行更新:

export const EntryDetail = () => {
  const { articleId } = useParams();
  const [article, setArticle] = useState({ title: null, body: null, comments: [], likes: [] });

  useEffect(() => {
    const getArticle = async () => {
      try {
        const response = await getArticleDetail(articleId);
        const { title, body, comments, likes } = response.data;
        setArticle({ title, body, comments, likes });
      } catch (e) {
        console.error(e);
      }
    };

    getArticle();
  }, [articleId]);

  return (
    <Container>
      {!article.title ? (
        <div>Loading...</div>
      ) : (
        <>
          <h1>{article.title}</h1>
          <p className="body">{article.body}</p>
        </>
      )}
    </Container>
  );
};

import { render, screen } from '@testing-library/react';
import { StateProvider } from '../../config/state';
import { EntryDetail } from './index';

const flushPromises = () => new Promise(resolve => setTimeout(resolve, 0));

vi.mock('react-router-dom', () => ({
  useParams: () => ({
    articleId: '63d466ca3d00b50db15aed93',
  }),
}));

describe("EntryDetail component", () => {
  it("should render the EntryDetail component correctly", async () => {
    render(
      <EntryDetail key={articleId} />
    );
    await flushPromises();
    const element = screen.getByRole("heading");
    expect(element).toBeInTheDocument();
  });
});
zi8p0yeb

zi8p0yeb3#

尝试更新此:

import { render, screen } from '@testing-library/react';
import { StateProvider } from '../../config/state';
import { EntryDetail } from './index';
import { act } from 'react-dom/test-utils';

const flushPromises = () => new Promise(resolve => setTimeout(resolve, 0));

vi.mock('react-router-dom', () => ({
  useParams: () => ({
    articleId: '63d466ca3d00b50db15aed93',
  }),
}));

describe("EntryDetail component", () => {
  it("should render the EntryDetail component correctly", async () => {
    await act(async () => {
      render(
        <EntryDetail />
      );
      await flushPromises();
    });
    const element = screen.getByRole("heading");
    expect(element).toBeInTheDocument();
  });
});

相关问题