簡體   English   中英

React-Testing-Library - 使用Redux和路由器包裝組件

[英]React-Testing-Library - Wrapping Component with Redux and Router

我正在嘗試設置測試文件以在我的應用程序上呈現路徑/頁面。 我正在嘗試使用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()
})

然后我收到以下錯誤:

Error: Uncaught [TypeError: Cannot read property 'params' of undefined]

拋出錯誤的原因是因為它無法找到React Router參數。 在Im初始化狀態時,它在組件構造函數中失敗:

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但忘記傳遞它收到的道具。 這就是為什么props.match在組件中未定義的原因。

你可以這樣做:

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

基本上,您可以使用3種方法之一使用<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')
})

編輯react-testing-library-examples

這就是我測試路線的方式。

  • 您使用react-redux作為Provider
  • 您為商店創建初始狀態
  • 將其添加到您的提供商
  • 現在你可以選擇元素,期望它們與你的html相匹配(每個例子)

    import { render } from '@testing-library/react';

    import { Router, Switch, Route } from 'react-router-dom';
    import { createMemoryHistory } from 'history';
    import { Provider } from 'react-redux';
    import React from 'react';
    import createStore from 'redux-mock-store';

    jest.mock('../../components/Form/ManagerSelect', () => jest.fn(() => null));

    describe('router page', () => {
      const createState = state => {
        return {
          //whatever u need
        }
      };

      const Home = _ => <span>home</span>;
      const Profile = _ => <span>profile</span>;

      const renderComponent = state => {
        const store = createStore()(state);

        //this is the "history" of your app like:
        // homepage -> about -> contact -> cart page ...

        const initialEntries = ['/'];
        return render(
          <Provider store={store}>
            <Router history={createMemoryHistory({ initialEntries })}>
              <Switch>
                <Route exact path="/" component={Home} />
                <Route exact path="/profile" component={Profile} />
              </Switch>
            </Router>
          </Provider>
        );
      };


      it('missing emergency details should redirect to profile', () => {
        const rendered = renderComponent(createState());
        expect(rendered.container.innerHTML).toEqual('<span>profile</span>');
      });

    });

React-testing-library 用<div>產生警告</div><div id="text_translate"><p>我正在使用 react-testing-library 來測試我的組件。 我有一個 TableHeader 組件,它是這樣的:</p><pre> &lt;thead&gt; // rest of content &lt;/thead&gt;</pre><p> 當我使用 RTL 對其進行測試以生成快照或任何內容時,我得到一個錯誤:</p><blockquote><p> 警告:validateDOMNesting(...): 不能作為子級出現</p></blockquote><p>最后我發現 RTS 為自己添加了一個環繞組件,它會導致錯誤。 可以在通過以下方式接收到的組件快照中看到:</p><pre> const { container } = render( &lt;TableHeader /&gt;, ); expect(container).toMatchSnapshot();</pre><p> 收到的快照:</p><pre> &lt;div&gt; &lt;thead&gt; // rest of component here &lt;/thead&gt; &lt;/div&gt;</pre><p> 為什么會這樣? 我沒有用&lt;div&gt;包裹整個組件,所以它不應該在那里......</p></div>

[英]React-testing-library wraps component with <div> which produces warning

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

相關問題 使用 Redux 和 react-testing-library 測試 React 組件 使用 TypeScript 的 Redux、路由器和動態模塊的 React-Testing-Library 設置 使用 react-testing-library 選擇子組件 react-testing-library react 測試組件更新 使用 test 和 react-testing-library 測試反應組件 React-testing-library:在組件上下文中找不到“商店” 如何使用 react-testing-library 測試由其他組件組成的組件? 測試組件使用自定義鈎子 react-testing-library React-testing-library 用<div>產生警告</div><div id="text_translate"><p>我正在使用 react-testing-library 來測試我的組件。 我有一個 TableHeader 組件,它是這樣的:</p><pre> &lt;thead&gt; // rest of content &lt;/thead&gt;</pre><p> 當我使用 RTL 對其進行測試以生成快照或任何內容時,我得到一個錯誤:</p><blockquote><p> 警告:validateDOMNesting(...): 不能作為子級出現</p></blockquote><p>最后我發現 RTS 為自己添加了一個環繞組件,它會導致錯誤。 可以在通過以下方式接收到的組件快照中看到:</p><pre> const { container } = render( &lt;TableHeader /&gt;, ); expect(container).toMatchSnapshot();</pre><p> 收到的快照:</p><pre> &lt;div&gt; &lt;thead&gt; // rest of component here &lt;/thead&gt; &lt;/div&gt;</pre><p> 為什么會這樣? 我沒有用&lt;div&gt;包裹整個組件,所以它不應該在那里......</p></div> 測試正確的 SVG 組件渲染與 jest 和 react-testing-library
 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM