首页 > 解决方案 > 如何测试 React-Redux???(useSelector)

问题描述

我是测试 react-redux 的新手。我有一个名为 OTARequestDetails 的组件,其中使用了减速器的状态,我试图访问该状态但收到以下错误:TypeError: Cannot read property 'otaRequestItem' of undefined。我尝试了许多不同的方法,但我无法理解为什么我无法访问 otaRequestItem。我已经单独测试了动作和减速器,现在两个测试都通过了我想测试组件。

零件:

import React, { useEffect, useState } from 'react'
import OTARequestCommandDetails from '../OTARequestCommandDetails'
import { otaStatusEnum } from '../../../constants'
import OTACommonHeader from '../OTACommonHeader'
import {
  SectionTitle,
  OTAStatusIcon,
} from '../../../common/components/SDKWrapper'
import { useSelector } from 'react-redux'
import { useAuth0 } from '@auth0/auth0-react'
import OTAModal from '../../../common/components/OTAModal'
import constants from '../../../constants'

function OTARequestDetails(props) {
  const { isAuthenticated } = useAuth0()
  const [isModalOpen, setIsModalOpen] = useState(false)
  const otaItem = useSelector((state) => state.otaReducer.otaRequestItem)
  const _constants = constants.OTAModal

  useEffect(() => {
    if (!isAuthenticated) {
      const { history } = props
      history.push({
        pathname: '/dashboard/ota',
      })
    }
  }, [])

  const onQuit = () => {
    setIsModalOpen(false)
  }

  const onAbortClick = () => {
    setIsModalOpen(true)
  }

  let abortInfo
  if (otaItem && otaStatusEnum.IN_PROGRESS === otaItem.status) {
    abortInfo = (
      <div>
        <span className="headerLabel"></span>
        <span className="infoLabel">
          OTA request is in-process of being delievered.
          <br />
          In-progress OTAs can be aborted. Please note this is irrevertible.
          <span className="link" onClick={() => onAbortClick()}>
            &nbsp;Abort in-progress OTA
          </span>
        </span>
      </div>
    )
  }

  return (
    <div className="otaRequestDetails">
      {otaItem && (
        <div>
          <OTACommonHeader title={'OTA Details'} />
          <div className="container">
            <div className="marginBottom20px">
              <SectionTitle text={constants.Forms.iccId.title} />
            </div>
            <div>
              <span className="headerLabel">Request ID:</span>
              <span>{otaItem.id}</span>
            </div>
            <div className="marginTop20px">
              <span className="headerLabel">ICCID to OTA:</span>
              <span>{otaItem.iccId}</span>
            </div>
            <div className="marginTop20px">
              <span className="headerLabel">Date Created:</span>
              <span>{otaItem.createdDate}</span>
            </div>
            <div className="marginTop20px">
              <span className="headerLabel">Date Delivered:</span>
              <span>{otaItem.createdDate}</span>
            </div>
            <div className="marginTop20px">
              <span className="headerLabel">Created By:</span>
              <span>{otaItem.requestedBy}</span>
            </div>
            <div className="marginTop20px">
              <span className="headerLabel">OTA Status:</span>
              <span>
                <OTAStatusIcon otaStatus={otaItem.status} />
                {otaItem.status}
              </span>
            </div>
            {abortInfo}

            <hr className="seperateLine" />

            <OTARequestCommandDetails otaItem={otaItem} />
          </div>
        </div>
      )}
      {isModalOpen && (
        <OTAModal
          _title={_constants.title}
          _description={_constants.description}
          _confirmText={_constants.confirmText}
          _onQuit={onQuit}
          isModalOpen={isModalOpen}
        />
      )}
    </div>
  )
}
export default OTARequestDetails
Test:

    import React from 'react'
    import { Provider } from 'react-redux'
    import { render, cleanup } from '@testing-library/react'
    import thunk from 'redux-thunk'
    import OTARequestDetails from '.'
    import configureStore from 'redux-mock-store'
    
    afterEach(cleanup)
    const mockStore = configureStore([thunk])
    
    describe('OTA Request Details', () => {
      test('should render', () => {
        const store = mockStore({
          otaRequestItem: {
            id: '20af3082-9a56-48fd-bfc4-cb3b53e49ef5',
            commandType: 'REFRESH_IMSIS',
            iccId: '789',
            status: 'DELIEVERED',
            requestedBy: 'testuser@telna.com',
            createdDate: '2021-04-29T07:08:30.247Z',
          },
        })
    
        const component = render(
          <Provider store={store}>
            <OTARequestDetails />
          </Provider>,
        )
       
        expect(component).not.toBe(null)
      })
    })

任何人都可以在我错的地方帮助我,为什么我不能访问减速器?提前致谢。

标签: reactjsreact-reduxjestjsreact-testing-library

解决方案


带选择器:

const otaItem = useSelector((state) => state.otaReducer.otaRequestItem);

您正在otaRequestItemstate.otaReducer对象访问。

在测试中,您的模拟商店在其对象中没有otaReducer属性。otaRequestItem在对象中嵌套otaReducer对象。

const store = mockStore({
  otaReducer: {
    otaRequestItem: {
      id: '20af3082-9a56-48fd-bfc4-cb3b53e49ef5',
      commandType: 'REFRESH_IMSIS',
      iccId: '789',
      status: 'DELIEVERED',
      requestedBy: 'testuser@telna.com',
      createdDate: '2021-04-29T07:08:30.247Z',
    },
  },
});

基本要点是......模拟商店只需要一个有效的对象形状,消费组件将尝试从中选择什么。


推荐阅读