【问题标题】:router.prefetch is not a function , Unable to check submit function in react testing libraryrouter.prefetch 不是函数,无法在反应测试库中检查提交函数
【发布时间】:2021-12-08 23:31:46
【问题描述】:

这是我的组件测试代码,我需要检查是否调用了表单提交函数。

import React from 'react'
import { render, screen, fireEvent, debug } from '@testing-library/react'
import '@testing-library/jest-dom'
import * as nextRouter from 'next/router'
nextRouter.useRouter = jest.fn()
nextRouter.useRouter.mockImplementation(() => ({ route: '/' }))
import Locations from '../pages/settings/locations'
import Add from '../pages/settings/locations/add'
import { act } from 'react-dom/test-utils'

describe('Add Locations', () => {
nextRouter.useRouter.mockImplementation(() => ({ route: '/settings/locations/add', pathname: '/settings/locations/add' })); // or which pathname you want to test
let companies = [
    {
        "name": "Fake Company Express",
        "phone": "9876543210",
        "email": "test@company.com",
        "contact": "Test",
        "address1": "Fake address1",
        "address2": "Fake address2",
        "address3": "",
        "city": "Fake City",
        "zip": "123456",
        "state": "State",
        "country": "Demo Test",
        "UUID": "9d8616dd-4689-4689-8812-a2345ccdcfc5"
    }
]

it('validate before save add location data', async () => {
        const mockAdd = jest.fn()
        const {getByLabelText, getByRole} = render(<Add data={companies} addLocation={mockAdd} />)

        const addButton = screen.getByTestId('addLocationBtn')

        await act(async () => {        

            fireEvent.change(getByRole("textbox", { name: /name/i }), {
                target: { value: "sds" }
            });
            fireEvent.input(getByRole("combobox", { name: /company/i }), {
                target: { value: "sdsd" }
            });
        })  

        await act(async () => {
          fireEvent.click(addButton);
        })
       expect(mockAdd).toHaveBeenCalled() 
  })

})

添加组件代码为:

import { useForm } from 'react-hook-form';
export default function Add({...props}) {
   const {
     register,
     handleSubmit,
     formState: { errors },
   } = useForm();

   const addLocation = async (data) => {
        console.log(data)
   }
   ......
   <form className="g-3" onSubmit={handleSubmit(addLocation)} data-testid="addLocationForm">
   <div className="col-md-4  col-lg-4 col-sm-6 mb-3">
     <label htmlFor="" className="form-label">Name</label>
                                                        
     <input type="text" {...register('name', { required: true })} className="form-control" data-testid="name" placeholder="Enter Name Here" />
                                                        {errors.name && <p className="error" role="error" data-testid="name_error">Name is required.</p>}
                                                    
 </div>
 <input type="submit" className="btn btn-primary float-end" value="Save Location" data-testid="addLocationBtn" />
 </form>
}

我正在使用反应钩子形式,得到错误

TypeError: router.prefetch 不是函数

【问题讨论】:

  • next/routerAdd 组件中使用在哪里?究竟是什么操作触发了错误?
  • Add 组件上没有使用 next/router。有一个提交按钮,点击调用保存功能
  • 如果该组件中没有使用next/router,为什么要在测试中模拟它?如果您出于某种原因确实需要模拟它,请确保它使用的所有函数都被模拟(在这种情况下,确保 router.prefetch 也被模拟)。
  • const mockAdd = jest.fn() const { getByTestId} = render() 用于测试它是否已调用addLocation 函数与否。我不应该这样做吗?
  • addLocation 是组件的内部函数,它不在组件的 props 中。与其测试它是否被调用,不如测试它是否正在执行预期的操作。

标签: reactjs jestjs react-router next.js react-testing-library


【解决方案1】:

每当我需要使用“next/router”时,我总是像这样调用 useRouter 并将其分配给一个变量:

import { useRouter } from "next/router"

const router = useRouter()

也许这有帮助

【讨论】:

  • 我应该在哪个文件上使用
  • 我在想你的第一个代码块的文件
猜你喜欢
  • 1970-01-01
  • 2021-02-17
  • 1970-01-01
  • 2021-08-22
  • 2018-10-21
  • 2021-10-22
  • 1970-01-01
  • 1970-01-01
  • 2020-07-17
相关资源
最近更新 更多