【问题标题】:getting TypeError: expect(...).toBeInTheDocument is not a function获取 TypeError: expect(...).toBeInTheDocument 不是函数
【发布时间】:2021-06-03 08:23:37
【问题描述】:

我正在尝试使用我的侧边栏组件进行单元测试,以检查呈现的文本是否在文档流中,它在文档流中,但测试用例失败说“ TypeError: expect(...).toBeInTheDocument 不是函数”。 不知道为什么会这样,我也导入了文件中的jest库,还是报同样的错误,求大神帮忙。

sidebar.spec.js 文件

import React from 'react';
import { shallow } from 'enzyme';
import { render, screen } from '@testing-library/react';
import '@testing-library/jest-dom';
import configureStore from 'redux-mock-store';
import toJson from 'enzyme-to-json';
import { Provider } from 'react-redux';

import Sidebar from './sidebar';

describe('Testing Sidebar component', () => {
    let wrapper, store;
    const mockStore = configureStore();
    const initialProp = {
        auth: {
            userAuth: {
                firstName: "savitha",
                lastName: "goel"
            }
        },
        meta: {
            productsMeta: [
                { label: "CX Admin Application" },
                { label: "Application Configuration Management" }
            ]
        }
    };

    beforeEach(() => {
        store = mockStore(initialProp);
        wrapper = shallow(<Sidebar store={store} />);
    });

    it('should be defined', () => {
        expect(wrapper).toBeDefined();
    });

    it('renders correctly', () => {
        expect(toJson(wrapper)).toMatchSnapshot();
    });

    it('render sidebar options as a text', () => {
        store = mockStore(initialProp);
        wrapper = shallow(
            <Provider store={store}>
                <Sidebar />
            </Provider>
        );

        console.log(store);

        console.log(screen.debug(null, Infinity))
        // const sidebarElement = screen.getByText('Application Manager');
        // expect(sidebarElement).toBeInTheDocument();
    });
});

我的 sidebar.js 文件

import React, { Component } from 'react'
import { connect } from 'react-redux';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faAngleDown, faWrench, faUserCircle, faHome, faDigitalTachograph, faMicrophone, faRecordVinyl } from '@fortawesome/free-solid-svg-icons';
import './_sidebar.scss';

class Sidebar extends Component {
    handleProductSelection(product) {
        this.props.props.history.push(product.path);
    }

    renderProducts = () => {
    if(this.props.products) {
      return this.props.products.map((product) => {
        return (<li onClick={() => this.handleProductSelection(product)}>{product.label}</li>);
      });
    }
    }

    render() {
        return(
      <div className="sidebar">
        <div className="profileWrap">
          <div>
            <div className="userNameWrap">
              <FontAwesomeIcon icon={faUserCircle} />
              <span className="userName">{this.props.firstName} {this.props.lastName}</span>
              <span className="angleIcon"><FontAwesomeIcon icon={faAngleDown} /></span>
            </div>
            <div className="userInfoWrap">
              <ul>
                <li>My profile</li>
                <li>Help with Console</li>
                <li>Contact us</li>
                <li>Log out</li>
              </ul>
            </div>
            <div className="divisionWrap">
              Division:
            </div>
          </div>
        </div>
        <div className="sidebarNavigation">
          <ul>
            <li>
              <div className="mainMenu">
                <FontAwesomeIcon icon={faHome} />
                <span className="menuName">Home</span>
              </div>
            </li>
            <li>
              <div className="mainMenu">
                <FontAwesomeIcon icon={faDigitalTachograph} />
                <span className="menuName">Mosaic Insights</span>
                <span className="angleIcon"><FontAwesomeIcon icon={faAngleDown} /></span>
              </div>
              <div className="subMenu">
                <ul>
                  {this.renderProducts()}
                </ul>
              </div>
            </li>
            <li>
              <div className="mainMenu">
                <FontAwesomeIcon icon={faWrench} />
                <span className="menuName">Application Manager</span>
                <span className="angleIcon"><FontAwesomeIcon icon={faAngleDown} /></span>
              </div>
              <div className="subMenu">
                <ul>
                  {this.renderProducts()}
                </ul>
              </div>
            </li>
            <li>
              <div className="mainMenu">
                <FontAwesomeIcon icon={faMicrophone} />
                <span className="menuName">Call Recording</span>
                <span className="angleIcon"><FontAwesomeIcon icon={faAngleDown} /></span>
              </div>
              <div className="subMenu">
                <ul>
                  {this.renderProducts()}
                </ul>
              </div>
            </li>
            <li>
              <div className="mainMenu">
                <FontAwesomeIcon icon={faWrench} />
                <span className="menuName">Console Administration</span>
                <span className="angleIcon"><FontAwesomeIcon icon={faAngleDown} /></span>
              </div>
              <div className="subMenu">
                <ul>
                  {this.renderProducts()}
                </ul>
              </div>
            </li>
          </ul>
        </div>
      </div>
    );
    }
}


const mapStateToProps = (state) => {
  return{
    firstName: state.auth.userAuth.firstName,
    lastName: state.auth.userAuth.lastName,
    products: state.meta.productsMeta
  };
};

export default connect(mapStateToProps)(Sidebar);

【问题讨论】:

  • 请用提供者包装你的侧边栏 - wrapper = shallow(&lt;Sidebar store={store} /&gt;);
  • @Shyam,如前所述,我用提供者包装了我的侧边栏,现在它给出了错误`ReferenceError: infinity is not defined`。
  • 抱歉,伙计。它必须是 InfinityI 大写。
  • @Shyam,我更新了问题中的文件 sidebar.spec.js,我运行了测试用例,它也通过了,但在控制台上它显示:console.log src/components/sidebar/sidebar.spec.js:50 { getState: [Function: getState], getActions: [Function: getActions], dispatch: [Function: dispatch], clearActions: [Function: clearActions], subscribe: [Function: subscribe], replaceReducer: [Function: replaceReducer] } console.log node_modules/@testing-library/dom/dist/pretty-dom.js:69 &lt;body /&gt; console.log src/components/sidebar/sidebar.spec.js:52 undefined
  • 对于console.log(screen.debug(null, Infinity)),它给出的是未定义的。

标签: javascript reactjs jestjs


【解决方案1】:

您需要用来自react-reduxProvider 包裹您的SideBar。因为你的 SideBar 是一个连接的组件。

import {Provider} from 'react-redux';

 <Provider store={store}>
     <Sidebar />
 </Provider>

还测试库提供了许多不同的工具来检查组件是否正确呈现。 screen.debug 就是这样一个有用的工具。

it('render sidebar options as a text', () => {   
        render( <Provider store={store}>
                 <Sidebar />
               </Provider>
         );

        console.log(screen.debug(null, Infinity)) 
    });

现在这会将整个 DOM 记录在终端的控制台中。

您正在使用酶和反应测试库。所以你需要在 2 个地方用 Provider 包裹你的侧边栏。

describe('Testing Sidebar component', () => {
  let wrapper, store;
  const mockStore = configureStore();
  const initialProp = {
    auth: {
      userAuth: {
        firstName: 'savitha',
        lastName: 'goel',
      },
    },
    meta: {
      productsMeta: [
        {label: 'CX Admin Application'},
        {label: 'Application Configuration Management'},
      ],
    },
  };

  beforeEach(() => {
    store = mockStore(initialProp);
    wrapper = shallow(
      // wrap it here .
      <Provider store={store}>
        <Sidebar />
      </Provider>
    );
  });

  it('should be defined', () => {
    expect(wrapper).toBeDefined();
  });

  it('renders correctly', () => {
    expect(toJson(wrapper)).toMatchSnapshot();
  });

  it('render sidebar options as a text', () => {
    store = mockStore(initialProp);
    render(
      // wrap it here as well .
      <Provider store={store}>
        <Sidebar />
      </Provider>
    );

    console.log(store);
    // screen is an API provided by testing library . You cannot use it with `shallow` from enzyme . So you need to use `render` instead of `shallow` for this IT block 
    console.log(screen.debug(null, Infinity));
    // const sidebarElement = screen.getByText('Application Manager');
    // expect(sidebarElement).toBeInTheDocument();
  });
});

【讨论】:

  • 我确实添加了 Provider 以及 store 作为 prop,但现在它给出了错误“TypeError: Cannot read property 'getState' of undefined”。
  • 这意味着您传递给提供者的商店是未定义的? .你可以在你的 it 块内和渲染上方做一个 console.log(store) 吗?
  • 我控制台登录商店,我也得到状态:{ auth: { userAuth: { firstName: 'savitha', lastName: 'goel' } }, meta: { productsMeta: [ [Object ], [Object] ] } } 但得到同样的错误。
  • 你能用你现在拥有的更新代码编辑你的答案吗?
  • 我已更新问题中的 sidebar.spec.js 文件。
猜你喜欢
  • 2018-09-13
  • 2016-03-03
  • 1970-01-01
  • 2019-05-27
  • 1970-01-01
  • 2019-08-08
  • 1970-01-01
  • 2019-10-26
  • 2020-05-22
相关资源
最近更新 更多