模拟服务工作者返回空

发布于 2025-01-27 02:03:52 字数 3879 浏览 4 评论 0原文

我是 React测试库的新手。我正在尝试测试一个调用某些API的简单组件 然后,它填充了这些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 />);
      });
}); 

程序

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];

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

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

测试

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>
    );
}

处理

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;
        }
    }

是 问题 ?

I'm new to react testing library. I am trying to test a simple component that call some apis
and then it fills inputs with the data of these apis. But when I run npm test it keeps showing me this : the recieved value is empty

Expected the element to have value:
100
Received:

   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)

here is my test

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());

My component

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>
    );
}

UPDATE

getClientInfo is a method that call my api using axios ( I put all my apis calls inside a file 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;
        }
    }

please what it could be the issue ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

谜兔 2025-02-03 02:03:52

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

因此,您需要等待该值,可以使用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();
  });
});

更新:

进行以下两个更改后,以上两种测试方法都可以正常工作。

  • 您已经创建了setUptests.ts api-mocks具有 no 效果的文件,因为CRA不考虑任何 setUptest.ts文件,但唯一的 src中的一个。您会注意到src中的文件已经有一个setuptest.ts,只需将所有设置代码移动到此文件中。

  • 模拟服务器返回一个数组,但是您的clientdata状态期望对象,因此请执行以下任一项:

    • 更新模拟服务器以返回对象而不是数组(在handlers.js中)
      js const client = {numerorc:“ 1000”,描述:“ desc One”,ifu:“ 100”,ICE:“ 789”,Company:“ Mycom”,City:“ Paris”};

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

        const response =等待getClientInfo();
      setClientData(响应[0]);
       

您还需要将onChange处理程序提供给所有输入,以摆脱警告。

The problem is that you're not awaiting for the value but the element, and the element is there when the component is mounted with a value of "", hence your assertion fails.

So, you need to await for the value, you can use waitFor for the same.

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");
    });
  });
});

You can also do it using 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();
  });
});

UPDATE:

Once you've made the following two changes, both the above methods of testing would work fine.

  • You've created a setupTests.ts file inside api-mocks which has no effect because CRA doesn't consider any setupTest.ts file but only the one that is there inside src. You would notice there's already a setupTest.ts file inside src, just move all your setup code into this file.

  • The mock server returns an array but your clientData state expects an object, so do either of the following:

    • Update the mock server to return an object instead of an array (in handlers.js)
      js const client = { numeroRc: "1000", description: "desc one", ifu: "100", ice: "789", company: "mycom", city: "paris" };

    • Or extract the object from the array before setting the state (in Client.tsx).

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

You also need to give an onChange handler to all your inputs to get rid of the warnings.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文