如何使用JEST在React中测试以下组件

时间:2018-07-09 06:32:22

标签: reactjs testing jestjs

我为“下载文件”创建了一个组件,该组件需要一些道具并单击按钮即可下载文件,它具有两个函数,分别调用showLoader和HideLoader

组件:以下是组件代码,该组件代码包含一些道具,并在用户单击该文件时创建了“下载”按钮。

import React from 'react'
import FileSaver from 'file-saver'
import axios from 'axios'

const DownloadFile = (props) => {

  const { url, title, callShowLoader, callHideLoader } = props

  const callDownloadFile = () => {
    callShowLoader()
    axios.get(url, { responseType: 'blob' }).then(res => {
      const fileName = res.headers['content-disposition'].match(/\"(.*?)"/)
      const fileToDownload = new Blob([res.data], {type: 'application/vnd.ms-excel;charset=charset=utf-8'})
      FileSaver.saveAs(fileToDownload, fileName[1])
      callHideLoader()
    })
  }

  return (<button className='mck-button-primary' title={title} onClick={e => callDownloadFile()}>
            <span className={"mck-icon__download mck-icon-no-pad"} />
          </button>)
}

export default DownloadFile

测试在这里,我正在测试组件,当用户单击下载按钮时无法测试,它给callShowLoader提供的功能不是错误

import React from 'react'
import { shallow, mount } from 'enzyme'
import DownloadFile from '../index.js'
import toJson from 'enzyme-to-json'
import axios from 'axios'

describe('<DownloadFile />', () => {
  const props = {
    callHideLoader: jest.fn(),
    callShowLoader: jest.fn(),
    title: 'Download Excel Report'
  }

  it('should render button title properly', () => {
    const wrapper = shallow(<DownloadFile {...props}/>)
    expect(wrapper.find('button').prop('title')).toEqual(props.title)
  })

  it('should call download file', () => {
    const callShowLoader = jest.fn()
    const wrapper = shallow(<DownloadFile {...props} callShowLoader={callShowLoader} />)
    wrapper.find('button').simulate('click')
    expect(callShowLoader).toHaveBeenCalled()
  })

  it('should match intial layout', () => {
    const wrapper = shallow(<DownloadFile {...props}/>)
    expect(wrapper.getElements()).toMatchSnapshot()
  })
})

2 个答案:

答案 0 :(得分:4)

DownloadFile上的onClick道具被完全忽略,因为您没有在DownloadFile组件的实现中使用它。

使用jest.fn()初始化callShowLoader和callHideLoader,将它们传递给DownloadFile组件(在初始化mountWrapper时),然后模拟onClick按钮并测试callShowLoader和callHideLoader是否都被调用。

答案 1 :(得分:1)

您没有在测试中通过callShowLoader作为道具,因此会出现callShowLoader is not a function错误。在您的beforeEach

中尝试一下
props = {
  callHideLoader: jest.fn(),
  callShowLoader: jest.fn(), 
  title: 'Download Excel Report'
}

然后在测试中

it('should call callShowLoader upon click', () => {
  const button = mountWrapper.find('button')
  button.simulate('click')
  expect(props.callShowLoader).toHaveBeenCalled()
})

通过这种方式,我看不出在这些测试中使用mount的任何理由,shallow应该为您完成工作。我总是将自己的内容写在测试用例中,以方便快捷地查看测试的内容,就像这样

it('should call callShowLoader upon click', () => {
  const wrapper = shallow(<DownloadFile ...props />);
  const button = wrapper.find('button')
  button.simulate('click')
  expect(props.callShowLoader).toHaveBeenCalled()
})

然后,我定义通过同一测试中特定测试所必需的道具,以最大程度地降低如果我在测试之外进行更改时测试将被破坏的风险。所以在这种情况下

import React from 'react'
import sinon from 'sinon';
import { shallow, mount } from 'enzyme'
import DownloadFile from '../index.js'
import toJson from 'enzyme-to-json'

describe('<DownloadFile />', () => {
  const props = {
    callHideLoader: jest.fn(),
    callShowLoader: jest.fn(),
    title: '',
  };

  it('should render button title properly', () => {
    const title = 'Download Excel Report';
    const wrapper = shallow(<DownloadFile {...props} title={title} />);
    expect(wrapper.find('button').prop('title')).toEqual(title)
  })

  it('should call download file', () => {
    sinon.stub(axios, 'get').returns(Promise.resolve());
    const callShowLoader = jest.fn();
    const wrapper = shallow(<DownloadFile {...props} callShowLoader={callShowLoader} />);

    wrapper.find('button').simulate('click')
    expect(callShowLoader).toHaveBeenCalled()
    expect(axios.get.callCount).to.equal(1);
  })

  it('should match initial layout', () => {
    const wrapper = shallow(<DownloadFile {...props} />);
    expect(wrapper.getElements()).toMatchSnapshot()
  })
})

...但这只是口味的问题:-)