【问题标题】:Jest unit testing a function that calls a function returning a PromiseJest 对调用返回 Promise 的函数的函数进行单元测试
【发布时间】:2020-11-30 16:45:36
【问题描述】:

我有一个函数调用一个返回 Promise 的函数。这是它的代码:

export const func1 = ({
  contentRef,
  onShareFile,
  t,
  trackOnShareFile,
}) => e => {
  trackOnShareFile()
  try {
    func2(contentRef).then(url => {
      onShareFile({
        title: t('shareFileTitle'),
        type: 'application/pdf',
        url,
      })
    }).catch(e => {
      if (process.env.NODE_ENV === 'development') {
        console.error(e)
      }
    })
    e.preventDefault()
  } catch (e) {
    if (process.env.NODE_ENV === 'development') {
      console.error(e)
    }
  }
}

func1 中调用的func2 是这样的:

const func2 = element => {
  return import('html2pdf.js').then(html2pdf => {
    return html2pdf.default().set({ margin: 12 }).from(element).toPdf().output('datauristring').then(pdfAsString => {
      return pdfAsString.split(',')[1]
    }).then(base64String => {
      return `data:application/pdf;base64,${base64String}`
    })
  })
}

现在我正在尝试为func1 编写一些单元测试,但遇到了一些问题。到目前为止我所做的是:

describe('#func1', () => {
  it('calls `trackOnShareFile`', () => {
      // given
      const props = {
        trackOnShareFile: jest.fn(),
        onShareFile: jest.fn(),
        shareFileTitle: 'foo',
        contentRef: { innerHTML: '<div>hello world</div>' },
      }
      const eventMock = {
        preventDefault: () => {},
      }
      // when
      func1(props)(eventMock)
      // then
      expect(props.trackOnShareFile).toBeCalledTimes(1)
    })
    it('calls `onShareFile` prop', () => {
      // given
      const props = {
        trackOnShareFile: jest.fn(),
        onShareFile: jest.fn(),
        shareFileTitle: 'foo',
        contentRef: { innerHTML: '<div>hello world</div>' },
      }
      const eventMock = {
        preventDefault: () => {},
      }
      // when
      func1(props)(eventMock)
      // then
      expect(props.onShareFile).toBeCalledTimes(1)
    })
  })

现在第一次测试通过,但第二次测试我得到Expected mock function to have been called one time, but it was called zero times.。我不确定如何正确测试它。任何形式的帮助都是可观的。

【问题讨论】:

  • 如果第一个通过但第二个失败,这仅意味着func2 失败。如果您删除 if (process.env.NODE_ENV === 'development') { 并记录错误,您将看到错误。在测试期间,您的环境可能是 test 而不是 development

标签: javascript reactjs unit-testing jestjs


【解决方案1】:

好的,我已经搞定了。

首先我们需要模拟出data-url-generator(这是我们导入func2的地方)。 html2pdf 库在测试环境中不起作用,因为它使用了一个没有完全实现画布图形的假 DOM。

jest.mock('./data-url-generator', () => jest.fn())

那么测试本身可以这样写:

it('invokes the `onShareFile` prop', done => {
    // given
    const t = key => `[${key}]`
    const urlMock = 'data:application/pdf;base64,PGh0bWw+PGJvZHk+PGRpdj5oZWxsbyB3b3JsZDwvZGl2PjwvYm9keT48L2h0bWw+'
    const shareFileTitle = 'bar'
    const contentRef = document.createElement('div')
    contentRef.textContent = 'hello world'
    const trackOnShareFile = () => { }
    const eventMock = {
      preventDefault: () => { },
    }
    func2.mockResolvedValue(urlMock)
    const onShareFileMock = ({ title, type, url }) => {
      // then
      expect(func2).toHaveBeenCalledTimes(1)
      expect(func2).toHaveBeenCalledWith(contentRef)
      expect(title).toBe('[shareFileTitle]')
      expect(type).toBe('application/pdf')
      expect(url).toBe(urlMock)
      done()
    }
    // when
    func1({
      contentRef,
      onShareFile: onShareFileMock,
      shareFileTitle,
      t,
      trackOnShareFile,
    })(eventMock)
  })

【讨论】:

    猜你喜欢
    • 2018-01-21
    • 2019-05-16
    • 1970-01-01
    • 2018-11-20
    • 1970-01-01
    • 2021-07-23
    • 1970-01-01
    • 2020-01-31
    • 2018-05-13
    相关资源
    最近更新 更多