模拟 Service Worker returns 空

Mock Service Worker returns empty

我是 React 测试库 的新手。我正在尝试测试一个调用一些 apis 的简单组件 然后它用这些 api 的数据填充输入。但是当我 运行 npm test 它一直向我显示:收到的值为空

预期元素具有值: 100 收到:

   7 |     it('displays returned client info on successful fetch', async () => {
   8 |       render(<Client />);
>  9 |       expect(await screen.findByLabelText('IFU')).toHaveValue('100');
     |                                                   ^
  10 |     });
  11 |
  12 |     it('displays error message when fetching tasks raises error', async () => {

  at Object.<anonymous> (src/unit-tests/Client.test.js:9:51)

这是我的测试

import { render, screen } from '@testing-library/react';
import Client from './../components/Client';
import { mswServer } from './api-mocks/msw-server';
import { clientHandlerException } from './api-mocks/handlers';

describe('Component: Client', () => {
    it('displays returned client info on successful fetch', async () => {
      render(<Client />);
      expect(await screen.findByLabelText('IFU')).toHaveValue('100');
    });

    it('displays error message when fetching tasks raises error', async () => {
        mswServer.use(clientHandlerException);
        render(<Client />);
      });
}); 

handlers.js

import { rest } from 'msw';

const importateur = {numeroRc: "1000", description: "desc one", ifu: "100",  ice: "789", company: "mycom", city: "paris"}

     export const clientHandler = rest.get("http://localhost:8080/api/informationsClient", async (req, res, ctx) => {
      // res(ctx.json(mockClientInfo))
      return res(
        ctx.status(200),
        ctx.json(importateur)
      )
    });
    
    export const clientHandlerException = rest.get("http://localhost:8080/api/informationsClient", async (req, res, ctx) =>
        res(ctx.status(500), ctx.json({ message: 'Deliberately broken request' }))
    );
    
    export const handlers = [clientHandler];

msw-server.js

import { setupServer } from 'msw/node';
import { handlers } from './handlers';

export const mswServer = setupServer(...handlers);

setupTests.js

import '@testing-library/jest-dom';
import { mswServer } from './msw-server';

beforeAll(() => mswServer.listen());
afterEach(() => mswServer.resetHandlers());
afterAll(() => mswServer.close());

我的组件

export interface IClient {
    numeroRc: string,
    description: string,
    ifu: string,
    ice: string
  }
  
const Client = (props: ClientProps) => {

const [clientData, setClientData] = React.useState<IClient>(
      {numeroRc: "",
      description: "",
      ifu: "",
      ice: ""}
    );
 //other useEffect s that call other apis  

 React.useEffect(() => {
        (async () => {      
          const response = await getClientInfo();
          setClientData(response as IClient);   
        })();  
  
    }, [])

    return(
        <Stack direction="row" spacing={3} className='client' >
            <TextField id="numro-rc" label="Numero RC" variant="outlined" value={clientData.numeroRc}/>
            <TextField id="client" label="Client" variant="outlined" value={clientData.description}/>
            <TextField id="ifu" label="IFU" variant="outlined" value={clientData.ifu} />
            <TextField title='ice' id="ice" label="ICE" variant="outlined" value={clientData.ice} />
        </Stack>
    );
}

更新

getClientInfo 是一种使用 axios 调用我的 api 的方法(我将所有 apis 调用放在文件 api.tsx 中)

axios.defaults.baseURL = 'http://localhost:8080/api'
...

    export const getClientInfo = async () => {
        try {
            const response =  await axios.get(`/informationsClient`);
            return response.data;  
        } catch(e) {
            console.log(e);
            return 0;
        }
    }

请问这可能是什么问题?

问题是您不是在等待值,而是在等待元素,并且当组件以 "" 的值安装时元素就在那里,因此您的断言失败。

因此,您需要 await 作为值,您可以使用 waitFor 作为相同的值。

import { render, screen, waitFor } from "@testing-library/react";

describe("Component: Client", () => {
  it("displays returned client info on successful fetch", async () => {
    render(<Client />);
    const element = screen.getByLabelText("IFU");
    await waitFor(() => {
      expect(element).toHaveValue("100");
    });
  });
});

您也可以使用 findByDisplayValue:

import { render, screen, waitFor } from "@testing-library/react";

describe("Component: Client", () => {
  it("displays returned client info on successful fetch", async () => {
    render(<Client />);
    const element = await screen.findByDisplayValue("100");
    expect(element).toBeInTheDocument();
  });
});

更新:

完成以下两项更改后,上述两种测试方法都可以正常工作。

  • 您在 api-mocks 中创建了一个 setupTests.ts 文件,该文件 没有 效果,因为 CRA 不考虑 任何 setupTest.ts文件,但只有 src里面的文件。您会注意到 src 中已经有一个 setupTest.ts 文件,只需将所有设置代码移至此文件即可。

  • 模拟服务器 return 是一个数组,但您的 clientData 状态需要一个对象,因此请执行以下任一操作:

    • 将模拟服务器更新为 return 对象而不是数组(在 handlers.js 中) js const client = { numeroRc: "1000", description: "desc one", ifu: "100", ice: "789", company: "mycom", city: "paris" };

    • 或者在设置状态之前从数组中提取对象(在Client.tsx)。

      const response = await getClientInfo();
      setClientData(response[0]);
      

您还需要为所有输入提供一个 onChange 处理程序以消除警告。