reactjs React测试库-如何Assert异步函数之间的中间状态?

wvt8vs2t  于 2023-03-29  发布在  React
关注(0)|答案(1)|浏览(148)

当我在浏览器中测试该组件时,它工作正常。单击按钮时,文本变为'bye'。几秒钟后,当数据提取完成时,它又变回'hi'。但在Jest中,它根本无法检测到'bye'文本。
我得到的错误是“TestingLibraryElementError:找不到具有以下文本的元素:/再见/我”
Test.jsx

import React, { useState } from 'react';
    export const Test = () => {
          const [isLeaving, setIsLeaving] = useState(false);
          const handler = async () => {
            setIsLeaving(true);
            const response = await fetch('https://api.jikan.moe/v4/anime/1/full');
            const data = await response.json();
            console.log({ data });
            setIsLeaving(false);
          };
          return (
            <div>
              <p>{!isLeaving ? 'hi' : 'bye'}</p>
              <button onClick={handler}>click me</button>
            </div>
          );
        };

Test.spec.jsx

import {render,screen,waitFor} from '@testing-library/react';
import userEvent from '@testing-library/user-event'; 
import { Test } from './Test';
import '@testing-library/jest-dom';
    
describe('Test component test', () => {
              global.fetch = jest.fn(() =>
                Promise.resolve({
                  json: () =>
                    Promise.resolve({
                      data: {
                        id: 1,
                        attributes: {
                          titles: { en: 'Fullmetal Alchemist' },
                          synopsis: 'After losine.'
                        }
                      }
                    })
                })
              );
              it('should show "bye" text before showing "hi" text when data fetching is don', async () => {
                const user = userEvent.setup();
                render(<Test />);
                expect(screen.getByText(/hi/i)).toBeInTheDocument();
                await user.click(screen.getByRole('button', { name: /click me/i }));
                expect(screen.getByText(/bye/i)).toBeInTheDocument();
                await waitFor(() => {
                  expect(screen.getByText(/hi/i)).toBeInTheDocument();
                });
              });
            });
u1ehiz5o

u1ehiz5o1#

res.json()方法创建延迟承诺。请在用户单击按钮后解决此问题。
index.tsx

import React, { useState } from 'react';

export const Test = () => {
  const [isLeaving, setIsLeaving] = useState(false);
  const handler = async () => {
    setIsLeaving(true);
    const response = await fetch('https://api.jikan.moe/v4/anime/1/full');
    const data = await response.json();
    console.log({ data });
    setIsLeaving(false);
  };
  return (
    <div>
      <p>{!isLeaving ? 'hi' : 'bye'}</p>
      <button onClick={handler}>click me</button>
    </div>
  );
};

index.test.tsx

import { render, screen, waitFor } from '@testing-library/react';
import '@testing-library/jest-dom';
import userEvent from '@testing-library/user-event';
import React from 'react';

import { Test } from './';

describe('Test component test', () => {
  const result = {
    data: {
      id: 1,
      attributes: {
        titles: { en: 'Fullmetal Alchemist' },
        synopsis: 'After losine.',
      },
    },
  };
  let jsonResolve;
  (global as any).fetch = jest.fn(() =>
    Promise.resolve({
      json: () =>
        new Promise((resolve) => {
          jsonResolve = resolve;
        }),
    })
  );
  it('should show "bye" text before showing "hi" text when data fetching is don', async () => {
    const user = userEvent.setup();
    render(<Test />);
    expect(screen.getByText(/hi/i)).toBeInTheDocument();
    await user.click(screen.getByRole('button', { name: /click me/i }));
    expect(screen.getByText(/bye/i)).toBeInTheDocument();
    jsonResolve(result);
    await waitFor(() => {
      expect(screen.getByText(/hi/i)).toBeInTheDocument();
    });
  });
});

试验结果:

PASS  stackoverflow/75861970/index.test.tsx (8.919 s)
  Test component test
    ✓ should show "bye" text before showing "hi" text when data fetching is don (139 ms)

  console.log
    { data: { data: { id: 1, attributes: [Object] } } }

      at stackoverflow/75861970/index.tsx:9:13

-----------|---------|----------|---------|---------|-------------------
File       | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-----------|---------|----------|---------|---------|-------------------
All files  |     100 |      100 |     100 |     100 |                   
 index.tsx |     100 |      100 |     100 |     100 |                   
-----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        9.337 s

相关问题