gpt4 book ai didi

reactjs - React-Testing-Library - 使用 Redux 和 Router 包装组件

转载 作者:行者123 更新时间:2023-12-03 13:42:39 25 4
gpt4 key购买 nike

我正在尝试设置一个测试文件来在我的应用程序上呈现路线/页面。我正在尝试用 Redux 和 Router 包装所有内容,这就是我所拥有的:

import React from 'react';
import { render } from 'react-testing-library';
import { createStore } from 'redux';
import { Provider } from 'react-redux';
import reducer from '../../store/reducer';
import {Link, Route, Router, Switch} from 'react-router-dom'
import {createMemoryHistory} from 'history'

import ViewNode from '../Pages/ViewNode';


const customRender = (
ui,
{
route = '/',
history = createMemoryHistory({ initialEntries: [route] }),
initialState,
store = createStore(reducer, initialState),
...options
} = {}
) => ({
...render(
<Provider store={store}>
<Router history={history}>{ui}</Router>
</Provider>,
options
),
history,
});

test('can render with redux and router', () => {
const { getByTestId } = customRender(
<Route path="/server/:env/:nodeName">
<ViewNode />
</Route>,
{
route: '/server/prod/some.server.name.com',
}
);

expect(getByTestId('page-content')).toBeVisible()
})

然后我收到以下错误:

错误:未捕获[TypeError:无法读取未定义的属性“params”]

抛出错误的原因是它找不到 React Router 参数。当我初始化状态时,组件构造函数失败:

this.state = {
modal: false,
activeTab: '1',
imageStatus: "loading",
env: props.match.params.env, //failing here
nodeName: props.match.params.nodeName,
environments: props.environments,
}

我上面的实现似乎没有正确包装路由器。

如何使用 Redux 和 Router 正确包装我的页面组件,以便它可以获得这些路由器参数?

最佳答案

您已放置 <ViewNode /> Route 内的组件但忘记传递它收到的 Prop 。这就是为什么props.match在您的组件中未定义。

您可以这样做:

    <Route path="/server/:env/:nodeName">
{props => <ViewNode {...props} />}
</Route>

基本上,你可以使用one of the 3 ways to render something with a <Route> .

<小时/>

这是一个工作示例:

import React from 'react'
import {Route, Router} from 'react-router-dom'
import {createMemoryHistory} from 'history'
import {render, fireEvent} from '@testing-library/react'
import {createStore} from 'redux'
import {Provider, connect} from 'react-redux'

function reducer(state = {count: 0}, action) {
switch (action.type) {
case 'INCREMENT':
return {
count: state.count + 1,
}
case 'DECREMENT':
return {
count: state.count - 1,
}
default:
return state
}
}

class Counter extends React.Component {
increment = () => {
this.props.dispatch({type: 'INCREMENT'})
}

decrement = () => {
this.props.dispatch({type: 'DECREMENT'})
}

render() {
return (
<div>
<div data-testid="env-display">{this.props.match.params.env}</div>
<div data-testid="location-display">{this.props.location.pathname}</div>
<div>
<button onClick={this.decrement}>-</button>
<span data-testid="count-value">{this.props.count}</span>
<button onClick={this.increment}>+</button>
</div>
</div>
)
}
}

const ConnectedCounter = connect(state => ({count: state.count}))(Counter)

function customRender(
ui,
{
initialState,
store = createStore(reducer, initialState),
route = '/',
history = createMemoryHistory({initialEntries: [route]}),
} = {},
) {
return {
...render(
<Provider store={store}>
<Router history={history}>{ui}</Router>
</Provider>,
),
store,
history,
}
}

test('can render with redux and router', () => {
const {getByTestId, getByText} = customRender(
<Route path="/server/:env/:nodeName">
{props => <ConnectedCounter {...props} />}
</Route>,
{
route: '/server/prod/some.server.name.com',
},
)

expect(getByTestId('env-display')).toHaveTextContent('prod')

expect(getByTestId('location-display')).toHaveTextContent(
'/server/prod/some.server.name.com',
)

fireEvent.click(getByText('+'))
expect(getByTestId('count-value')).toHaveTextContent('1')
})

Edit react-testing-library-examples

关于reactjs - React-Testing-Library - 使用 Redux 和 Router 包装组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55803025/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com