【问题标题】:How to create a mock POST request to test if page has changed如何创建模拟 POST 请求以测试页面是否已更改
【发布时间】:2021-08-06 11:51:27
【问题描述】:

我有一个 App.js 文件,其中包含一个表单,提交时会触发状态更改以呈现新页面。我正在尝试创建一个执行以下步骤的模拟 Jest 测试:

  1. 获取模拟数据
  2. 像 addInfo 一样发送 POST 请求
  3. 检查“DONE WITH FORM”是否呈现在屏幕上。

我也有一个想法,我们可以填写一个包含 valid_address 和 valid_number 的表格,然后单击一个按钮触发 addInfo 函数以使用传入的信息运行,但是我不确定该方法,它会导致我遇到了 CORS 错误。

从我在网上看到的情况来看,我认为使用 Jest 模拟这个 addInfo,然后测试渲染的内容是最好的方法,但是我完全坚持构建这个测试。

这是我的 App.js 的内容

const addInfo = async (formInfo) => {
    try {
      let data = {
        valid_number: formInfo.validNumber,
         valid_address: formInfo.validAddress
      }

      let addUserUrl = process.env.REACT_APP_URL +'/verify'
      let addUserData = await fetch(
        addUserUrl,
        { 
          method: "POST",
          headers: {
            "Content-type": "application/json",
            "x-api-key": process.env.REACT_APP_KEY
          },
          body: JSON.stringify(data)
        }
      )
      if (addUserData.status !== 200) {
        throw 'Error adding User'
      }

      let addUserDataJson = addUserData.json()

      let ret = {
        added: true,
      }
      return ret
    } catch (error) {
      console.log('Error')
      let ret = {
        added: false,
      }
      return ret
    }
  }


  const onFinish = async (values: any) => {
      console.log('Transaction verified');
      let addStatus = await addInfo({
        validNumber: "123434",
        validAddress: "D74DS8JDSF",
      })

      if (promoStatus.added) {
        setState({
          ...state,
          showPage: false
        })
      } else {
        setState({
          ...state,
          showPage: true
        })
      }
   };

return (
 {!state.showPage &&
          <>
           <div>
                  <p>
                   DONE WITH FORM
                  </p>
            <div>
          </>
        }
)

这是我在 App.test.js 中尝试过的:

it('DONE WITH FORM APPEARS', async() =>{

  
            
            // Render App 
          const { getByPlaceholderText, queryByText, getByText } = render(<App />);
            // Entering Valid Number 
           const validNumberInputBox = getByText('Enter Valid Number);
           fireEvent.change(validNumberInputBox, { target: { value: "123434" } });
           expect(validNumberInputBox).toHaveValue("123434");

           // Entering Valid Address
           const validAddressInputBox = getByText('Enter Valid Address');
           fireEvent.change(validAddressInputBox, { target: { value: "D74DS8JDSF" } });
           expect(validAddressInputBox).toHaveValue("D74DS8JDSF");
           
           

           // Button Click
           userEvent.click(screen.getByRole('button', {name: /Submit/i}));
         
          //Check if the DONE WITH FORM is shown 
          expect(await waitFor(() => getByText('DONE WITH FORM'))).toBeInTheDocument();
    });

我已经尝试了几乎所有可以通过其他堆栈溢出帖子和网络文章找到的东西。所以我非常感谢有关如何实施此单元测试的任何帮助。

【问题讨论】:

    标签: javascript reactjs unit-testing jestjs react-testing-library


    【解决方案1】:

    第一步是模拟执行 POST 请求 (addInfo) 的异步函数。您永远不想在单元测试中尝试真正的 HTTP 请求(这不会起作用,因为 Jest 在未实现 fetch 或 XMLHttpRequest API 的 Node 环境中运行)。除此之外,组件/单元测试应该独立于任何其他系统,例如后端公开 API。

    为此,你的异步函数应该在一个单独的文件中(所以是一个 JS 模块),然后你可以使用 Jest 模拟这个模块:

    // api.js
    export const addInfo = () => {...}
    
    // App.test.js
    import * as Api from 'api.js';
    
    // here you can define what your mock will return for this test suite
    const addInfoSpy = jest.spyOn(Api, 'addInfo').mockResolvedValue({ ret: true });
    
    describe('...', () => {
      test('...', async () => {
        // perform user interactions that should trigger an API call
        expect(addInfoSpy).toHaveBeenCalledWith('expected addInfos parameter');
        // now you can test that your component displays "DONE WITH FORM" or whatever
        // UI it should be displaying after a successful form submission
      });
    });
    

    【讨论】:

    • 感谢您非常清楚的解释!我不知道我不应该测试 POST 请求。为什么我看到很多人在其他堆栈溢出帖子/网络文章中模拟 GET 请求?
    • 在组件测试中,您应该模拟所有 HTTP 请求(GET、POST、PUT、DELETE...)。所以我发现维护 JS 模块非常方便,您可以在其中定义异步函数,匹配您的后端 API,因此您始终可以只模拟组件测试中需要的内容。这些测试应该通过集成或端到端测试、真正的后端和真正的 REST(或 GraphQL)服务来完成。在网络世界中,这可以使用 Cypress、Nightwatch、Selenium 或其他 E2E 网络测试框架来完成。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-02-14
    • 1970-01-01
    • 2020-07-16
    • 2012-07-08
    • 1970-01-01
    • 2022-01-08
    • 2021-12-09
    相关资源
    最近更新 更多