标签: react-testing-library

在react-router的路由中进行基于路由的测试的推荐方法

我正在我的一个项目中使用react-testing-library,并尝试编写验证应用内路由的测试。

例如,测试 AccessDenied 页面上的按钮是否会将您带回主页。

我已经能够为我的应用程序组件成功编写这些类型的测试,因为它定义了所有应用程序路由。但是,如果 AccessDenied是这些路由之一,我需要如何设置测试来验证单击那里的按钮是否会将我路由回主页?

这是一个人为的例子:

应用程序.tsx

<>
  <Router>
    <Route exact path="/" component={Home} />
    <Route exact path="/access-denied" component={AccessDenied} />
  </Router>
  <Footer />
</>
Run Code Online (Sandbox Code Playgroud)

拒绝访问.tsx

<div>
  <div>Access Denied</div>
  <p>You don't have permission to view the requested page</p>
  <Link to="/">
    <button>Go Home</button>    <--- this is what i want tested
  </Link>
</div>
Run Code Online (Sandbox Code Playgroud)

正如我之前所说,我的测试在内部工作的原因App.test.tsx是因为我的应用程序组件定义了其内部的路由,而我的AccessDenied只是其中之一。App.tsx但是,是否可以在我的测试中利用我定义的路由器AccessDenied.test.tsx?也许我处理这个问题的方式不正确?这就是我挣扎的地方。作为参考,这是我的工作App.test.tsx测试。

应用程序.test.tsx

describe('App', () => {
  it('should allow you to navigate to login', async () => {
    const …
Run Code Online (Sandbox Code Playgroud)

integration-testing unit-testing reactjs jestjs react-testing-library

2
推荐指数
1
解决办法
4910
查看次数

如何在 useEffect 中测试具有异步状态更新的钩子?

我有一个简单的钩子,可以获取值并将其设置为选项,如下所示:

import Fuse from 'fuse.js'
import React from 'react'

// prefetches options and uses fuzzy search to search on that option
// instead of fetching on each keystroke
export function usePrefetchedOptions<T extends {}>(fetcher: () => Promise<T[]>) {
  const [options, setOptions] = React.useState<T[]>([])
  React.useEffect(() => {
    // fetch options initially
    const optionsFetcher = async () => {
      try {
        const data = await fetcher()
        setOptions(data)
      } catch (err) {
        errorSnack(err)
      }
    }
    optionsFetcher()
  }, [])
  // const fuseOptions = {
  // …
Run Code Online (Sandbox Code Playgroud)

testing reactjs react-testing-library react-hooks-testing-library

2
推荐指数
1
解决办法
1万
查看次数

如何使用react-testing-library使用ref测试逻辑并更新useEffect/useLayoutEffect内的状态

我的组件用于useLayoutEffect执行一个函数来计算位置的两个状态变量。相同的函数被传递给内部容器之一的 Element.scroll 事件:

代码如下所示:

export const Component = ({children}) => {
    // .....

    const containerRef = useRef<HTMLDivElement>(null);
    const [canClickLeft, setCanClickLeft] = useState(false);
    const [canClickRight, setCanClickRight] = useState(false);

    const checkForPosition = () => {
      if (containerRef.current) {
        // logic here;

        const positionLeft = false;
        const positionRight = true;
  
        setCanClickLeft(positionLeft);
        setCanClickRight(positionRight);
      }
    };

    const doSomething = () = {....}
  
    useLayoutEffect(() => {
        checkForPosition();
    });


    return (
      <>
        <StyledContainer onScroll={() => checkForPosition()}>
          {children}
        </StyledContainer>
  
        <button disabled={!canClickLeft} onClick={doSomething}>Click Left</button>
        <button disabled={!canClickRight onClick={doSomething}}>Click …
Run Code Online (Sandbox Code Playgroud)

reactjs react-testing-library react-hooks

2
推荐指数
1
解决办法
3933
查看次数

你如何模拟 useDebounce ?

所有模拟尝试都会产生错误:

import useDebounce from 'use-debounce'
jest.mock('use-debounce')

TypeError: (0 , _useDebounce.useDebounce) is not a function or its return value is not iterable
Run Code Online (Sandbox Code Playgroud)

尝试仅针对该模拟也失败:

jest.mock('use-debounce',() => {
  return {
    useDebounce: jest.fn(value => [value])
  }
})
Run Code Online (Sandbox Code Playgroud)

也给出了同样的错误。使用模拟计时器也不起作用。

javascript debouncing jestjs react-testing-library react-hooks

2
推荐指数
1
解决办法
1826
查看次数

如何使用 'toHaveClass' 来匹配 Jest 中的子字符串?

我正在给一个元素上课success。但是 React-Mui 在 DoM 上附加了一个文本,比如mui-AbcXYZ-success. 所以当我这样做时

\n

expect( getByTestId('thirdCheck')).toHaveClass("success")

\n

我没有通过这个测试,因为它需要完整的名称mui-AbcXYZ-success。仅当我提供确切的名称(带有连字符的文本和 mui 添加的随机数)时,I\xe2\x80\x99m 才能通过此操作

\n

我该如何测试呢?

\n

我尝试执行以下操作但没有结果:\nexpect( getByTestId('thirdCheck')).toHaveClass(/success/)

\n

我也尝试应用 .classNameor.classList但这并没有\xe2\x80\x99t 给我元素上的类列表。

\n

javascript reactjs jestjs material-ui react-testing-library

2
推荐指数
2
解决办法
1万
查看次数

“instanceof”的右侧不是 React 测试库中的对象

我正在为我的 React 组件创建一个测试。该组件使用该window.dataLayer.push函数将事件发送到 Google 跟踪代码管理器。

测试时,我得到的window.dataLayer.pushundefined,然后我在我的文件中创建了一个模拟setupTests.ts

import "@testing-library/jest-dom/extend-expect";
import { server } from "mocks/server";

beforeAll(() => {
  server.listen();
});
beforeEach(() => {
  Object.defineProperty(global, "window", {
    value: {
      dataLayer: {
        push: jest.fn(),
      },
    },
  });
});
afterEach(() => {
  server.resetHandlers();
});
afterAll(() => {
  server.close();
});
Run Code Online (Sandbox Code Playgroud)

现在我得到了一个TypeError: Right-hand side of 'instanceof' is not an object. 这发生在我的render函数中:

TypeError: Right-hand side of 'instanceof' is not an object

       5 |
       6 | …
Run Code Online (Sandbox Code Playgroud)

reactjs react-testing-library

2
推荐指数
1
解决办法
8734
查看次数

测试时,导致 React 状态更新的代码应包装到 act(...)

我正在测试我的组件

ForecastButtons.js

export const ForecastButtons = ({ city }) => {
  const [payload, setPayload] = useState(null)

  const getData = () => {
    fetchCityData(city).then((payload) => setPayload(payload));
  }
  const location = payload?.location?.name;
  const currentTemp = payload?.current?.temp_c;

  return(
    <div className="sm:col-span-2">
      <p className="block text-sm font-medium text-gray-700">Select forecast</p>
        <button onClick={getData} className="mt-1 bg-transparent hover:bg-blue-500 text-blue-700 font-semibold hover:text-white py-2 px-4 border border-blue-500 hover:border-transparent rounded" type='button'>
          Today
        </button>
        <p key={city?.location?.id} className='my-5'>
          { location ? `Current weather in ${location} is ${currentTemp} degrees ` : 'Please search for city to …
Run Code Online (Sandbox Code Playgroud)

reactjs jestjs react-testing-library

2
推荐指数
1
解决办法
1472
查看次数

使用 Jest 模拟 API 错误响应时,组件中的 Fetch 未定义

我正在测试一个组件,该组件使用一个useEffect钩子从 API 获取数据,更新状态,然后构建组件。我已经使用Stack Overflow 答案作为示例成功模拟了几次测试的 API 响应。我现在正在尝试编写一个测试,在其中模拟从 API 返回的错误。我收到一条错误,TypeError: Cannot read property 'then' of undefined指出fetch. 我正在尝试使用相同的示例,但没有成功。

我成功地使用测试数据获取模拟如下所示:

global.fetch = jest.fn().mockImplementationOnce(() =>
  Promise.resolve({
    json: () => Promise.resolve(successMockData),
  })
)
Run Code Online (Sandbox Code Playgroud)

我尝试的模拟错误响应当前如下所示:

global.fetch = jest.fn().mockImplementationOnce(() => {
  Promise.resolve({
    status: 400,
    json: () => Promise.resolve({ success: false, error: 'Something bad happened' }),
  })
})
Run Code Online (Sandbox Code Playgroud)

运行测试时我得到的错误是: 在此输入图像描述

如果我拒绝承诺,我仍然会得到相同的错误,但也会引发抛出的异常:

global.fetch = jest.fn().mockImplementationOnce(() => {
  Promise.reject({
    status: 400,
    json: () => Promise.resolve({ success: false, error: 'Something bad happened' }),
  }) …
Run Code Online (Sandbox Code Playgroud)

unit-testing reactjs jestjs react-testing-library

2
推荐指数
1
解决办法
4748
查看次数

如何进行一个在检查元素外观之前等待 5 秒的测试(React 测试库)

在我的反应组件中,我有一个 5 秒后出现的元素。

我想做一个测试,检查 5 秒后元素是否出现jest fake timers,但无法使其工作......

我在这里做错了什么?

其中一个示例不起作用:

it('check step 2 labels text, status "Submitted"', async () => {
    render(<ProgressIndicator appStatus="submitted" />);

    jest.advanceTimersByTime(5005);
    await waitFor(() => {
      expect(
        screen.getByText('Beep. Boop. Still doing our thing here.'),
      ).toBeInTheDocument();
    });

    await waitFor(() => {
      expect(screen.getByText('Verifying identity...')).toBeInTheDocument();
    });
  });
Run Code Online (Sandbox Code Playgroud)

第二个例子:

it('check step 2 labels text, status "Submitted"', async () => {
    render(<ProgressIndicator appStatus="submitted" />);

    act(() => {
      jest.advanceTimersByTime(5005);
    });

    expect(
      screen.getByText('Beep. Boop. Still doing our thing here.'),
    ).toBeInTheDocument();
    expect(screen.getByText('Verifying identity...')).toBeInTheDocument(); …
Run Code Online (Sandbox Code Playgroud)

javascript unit-testing reactjs jestjs react-testing-library

2
推荐指数
1
解决办法
3万
查看次数

如何在反应测试库中暂停模拟服务工作人员以测试中间状态?

我正在使用 MSW(模拟服务工作线程)通过 React 测试库来模拟我的 React 测试中的 HTTP 响应。但是,在某些反应组件中,我有一些加载状态,直到响应完成。

为了测试中间加载状态,有没有办法暂停正在进行的 Service Worker API 并进行一些测试(这样可以保证测试的一致性),然后继续进行进一步的测试?

unit-testing reactjs react-testing-library msw

2
推荐指数
1
解决办法
1868
查看次数