如何测试在Jest / Enzyme中超出组件范围定义的无状态组件中使用的功能?

问题描述 投票:0回答:1

我正在尝试为以下各项编写测试:

import React from 'react'
import Popup from 'some-library'

const popupConfig = {
  home: {
    popupValue: 'Hello World',
    popupValue: 'action',
    popupMessage: 'Get Started'
  },
  settings: {
    popupValue: 'Hello World',
    popupValue: 'action',
    popupMessage: 'Get Started'
  }
}

const closePopup = () => {
  Popup.closePopup()
}

const toggleNewPopup = () => {
  Popup.togglePopup('some-popup')
}

const GetStartedPopup = ({ moduleName }) => {
  if (!Object.keys(popupConfig).includes(moduleName)) return null
  const {
    popupValue = 'Hi there!',
    popupStyle = 'warning',
    popupMessage = 'Get Started',
    popupBtnFunction = toggleNewPopup
  } = popupConfig[moduleName]

  return (
    <Popup
      popupValue={popupValue}
      popupStyle={popupStyle}
      popupBtnValue={popupMessage}
      popupBtnStyle="neutral"
      popupBtnFunction={popupBtnFunction}
      xPopup={closePopup}
    />
  )
}

export default GetStartedPopup

测试的目的是确保调用closePopuptoggleNewPopup函数。我正在为closePopup function执行以下操作:

import React from 'react'
import { mount } from 'enzyme'
import { Popup } from 'some-library'
import GetStartedPopup from 'widgets/getStartedPopup'

describe('<GetStartedPopup/>', () => {
    let wrapper
    let props
    beforeEach(() => {
        props = {
            page: 'home'
        }
        wrapper  = mount(<GetStartedPopup {...props}/>)
    })

    it('should render the component without crashing', () => {
        expect(wrapper).toBeDefined();
    })

    it('should call closePopup', () => {
        const spy = jest.spyOn(wrapper.instance(), 'closePopup');
        wrapper.instance().closePopup();
        expect(spy).toHaveBeenCalledTimes(1);
    })

    afterEach(() => {
        wrapper.unmount()
    })
})

我浏览了spyOn和其他SO线程的文档,这些文档解决了类似的问题,但是在这里无法解决如何测试closePopuptoggleNewPopup函数的情况。当我运行上面编写的测试用例时,我得到的是:TypeError: Cannot read property 'closePopup' of null。编写测试以确保调用两个函数的正确方法是什么?

reactjs unit-testing jestjs enzyme
1个回答
0
投票

我在工作中遇到wrapper.instance() doc时对此感到很有趣

要返回整个React组件的道具,请使用wrapper.instance()。props。这对于React 15中的有状态或无状态组件有效。.但是,wrapper.instance()对于React 16中的无状态React组件将返回null,因此wrapper.instance()。props在这种情况下会导致错误。

关于第三方图书馆。您应该嘲笑您的组件使用的任何协作者。

import { Popup } from 'some-library';
describe('<GetStartedPopup />', () => {
  let wrapper;

  jest.mock('some-library', () => {
    Popup: jest.fn(),
  });

  const initialProps = {
    page: 'home'
  };

  const getStartedPopup = () => {
    return mount(<GetStartedPopup {...initialProps});
  };

  beforeEach(() => {
    Popup.mockClear()
    wrapper = getStartedPopup();
  };

  it('should call closePopup', () => {
    expect(Popup.closePopup()).toHaveBeenCalledTimes(1);
  });
  ...
});
© www.soinside.com 2019 - 2024. All rights reserved.