首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >React测试库:如何测试包含useLocation()的组件?

React测试库:如何测试包含useLocation()的组件?
EN

Stack Overflow用户
提问于 2020-12-20 05:54:40
回答 1查看 1.2K关注 0票数 5

我使用的是RedwoodJS,它使用的是。由于useLocation()钩子,我很难测试一个组件(以及所有在树中包含该组件的页面组件)。

当在组件中使用useLocation()钩子时,我需要用一个模拟浏览器位置历史的路由器包装正在测试的组件,以防止错误Error: Uncaught [TypeError: Cannot read property 'pathname' of undefined]

但是,当我这样做时,导航组件将不再完全呈现,所以我无法测试它.有什么想法吗?

Navigation.js

代码语言:javascript
复制
//import statements

const renderListItems = (pathname) => {
  const NavigationItems = [{..},{..},{..}] // example

  return NavigationItems.map((item) => {
    const selected = pathname.indexOf(item.path) ? false : true
    return (
      <ListItem
        button
        key={item.text}
        onClick={() => {
          navigate(item.route)
        }}
        selected={selected}
      >
        <ListItemText primary={item.text} />
      </ListItem>
    )
  })
}

const Navigation = () => {
  const { pathname } = useLocation() // this is why I need to wrap the Navigation component in a router for testing; I'm trying to get the current pathname so that I can give a specific navigation item an active state.

  return (
    <List data-testid="navigation" disablePadding>
      {renderListItems(pathname)}
    </List>
  )
}

export default Navigation

Navigation.test.js

代码语言:javascript
复制
import { screen } from '@redwoodjs/testing'
import { renderWithRouter } from 'src/utilities/testHelpers'

import Navigation from './Navigation'

describe('Navigation', () => {
  it('renders successfully', () => {
    expect(() => {
      renderWithRouter(<Navigation />)
    }).not.toThrow()
  })
  it('has a "Dashboard" navigation menu item', () => {
    renderWithRouter(<Navigation />)
    expect(
      screen.getByRole('button', { text: /Dashboard/i })
    ).toBeInTheDocument()
  })
})

testHelpers.js

这是防止useLocation()在Navigation.js中破坏测试所必需的。

代码语言:javascript
复制
import { Router, Route } from '@redwoodjs/router'
import { createMemoryHistory } from 'history'
import { render } from '@redwoodjs/testing'
const history = createMemoryHistory()

export const renderWithRouter = (Component) =>
  render(
    <Router history={history}>
      <Route component={Component} />
    </Router>
  )

结果误差

代码语言:javascript
复制
Navigation › has a "Dashboard" navigation menu item

TestingLibraryElementError: Unable to find an accessible element with the role "button"

    There are no accessible roles. But there might be some inaccessible roles. If you wish to access them, then set the `hidden` option to `true`. Learn more about this here: https://testing-library.com/docs/dom-testing-library/api-queries#byrole

    <body>
      <div />
    </body>
EN

回答 1

Stack Overflow用户

发布于 2021-11-11 01:56:10

您可以模拟useLocation以返回所需的路径名。这可以适用于任何函数。

简单

代码语言:javascript
复制
//Put within testing file
jest.mock("router-package", () => ({
  ...jest.requireActual("router-package"),
  useLocation: () => ({
    pathname: "customPath/To/Return"
  })
}));

详细信息

您可以创建一个帮助函数,在那里您可以传递路径(string),并且它会自动地为您模拟路径。

random.test.js

代码语言:javascript
复制
import { setUpPageRender } from 'src/utilities/testHelpers'
import Navigation from './Navigation'

describe('Navigation', () => {
  //Where we set up our custom path for the describe
  const render = setUpPageRender('/customPathForThisDescribe/Foo')

  it('renders successfully', () => {
    expect(() => {
      render(<Navigation />)
    }).not.toThrow()
  })
})

testHelpers.js

代码语言:javascript
复制
//Mocked Functions
jest.mock('router-package', () => ({
  __esModule: true,
  ...jest.requireActual('router-package'),
  useLocation: jest.fn(),
}))
import { useLocation } from 'router-package'


export const setUpPageRender = (location) => {
  useLocation.mockReturnValue(location)

  beforeEach(() => {
    jest.clearAllMocks()
  })

  return (component) => {
    return render( <Router history={history}>
      <Route component={Component} />
    </Router>)
  }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65377303

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档