首页 > 解决方案 > Unable to Ignore Block within React Class Components with istanbul ignore next to gain coverage

问题描述

我正在为使用Gatsby. 我需要能够提供 100% 的覆盖率。我无法对源代码进行重大编辑,因为我没有构建站点,也不拥有代码,以免我冒着破坏 UI 的风险(我不做快照或 UI 测试)。

我一直在 Github 问题、Stack Overflow 等中寻找答案,似乎在使用/* istanbul ignore next */.

使用 Gatsby,您必须检查对window任何脚本或 Web API 的引用,并有条件地忽略该代码 if typeof window === 'undefined',因为 Gatsby 在服务器上静态生成站点。为了增加对这些语句、分支、函数和行的覆盖,我已经能够使用/* istanbul ignore next */. 但是,我在使用特定的类组件时遇到了困难。

我尝试在生命周期定义中,在函数名和括号之间,在生命周期中的块之前使用/* istanbul ignore next */beforecomponentDidMount和。我也尝试过使用.componentDidUpdateif/* istanbul ignore if */

无论我使用什么代码,我都无法覆盖。我对这里的任何建议持开放态度,无论是使用ignore语句的更好方法还是关于创建可以解决问题的测试的方法的提示。谢谢您的帮助!

以下是组件的可发现(到目前为止)行:

职业生涯.js

  componentDidMount() {
    this.context.setHeaderTheme(`bright`)
    /* istanbul ignore next */
    if (typeof window !== `undefined` && typeof document !== `undefined`) {
      if (!window.Grnhse) {
        const script = document.createElement(`script`)
        script.setAttribute(
          `src`,
          `<hidden/path/for/security/purposes>`
        )
        script.setAttribute(`width`, `100%`)
        script.onload = () => window.Grnhse && window.Grnhse.Iframe.load()
        document.body.appendChild(script)
      } else {
        if (window.Grnhse) {
          window.Grnhse.Iframe.load()
        }
      }
    }
  }

  componentDidUpdate() {
    /* istanbul ignore next */
    if (
      !this.scrollDone &&
      typeof window !== `undefined` &&
      window.location.search.includes(`gh_jid`) &&
      this.greenhouseContainer
    ) {
      this.scrollDone = true
      window.scrollTo({
        top: this.greenhouseContainer.offsetTop,
        behavior: `smooth`,
      })
    }
  }  

标签: reactjsjestjsgatsbyreact-testing-libraryistanbul

解决方案


我想我找到了一个有效的答案。

jest.config.jsJest 版本 26.0 中,您可以将其配置coverageProviderbabel(默认)或v8(被认为是实验性的)。

我更改为v8并安装v8-to-istanbul

npm i --save-dev v8-to-istanbul

这提供了一些似乎可以创造奇迹的新功能。我得到了 100% 的覆盖率,但functions很快。

    /* c8 ignore next 16 */
    if (typeof window !== `undefined` && typeof document !== `undefined`) {
      if (!window.Grnhse) {
        const script = document.createElement(`script`)
        script.setAttribute(
          `src`,
          `...`
        )
        script.setAttribute(`width`, `100%`)
        script.onload = () => window.Grnhse && window.Grnhse.Iframe.load()
        document.body.appendChild(script)
      } else {
        if (window.Grnhse) {
          window.Grnhse.Iframe.load()
        }
      }
    }
    /* c8 ignore next 13 */
    if (
      !this.scrollDone &&
      typeof window !== `undefined` &&
      window.location.search.includes(`gh_jid`) &&
      this.greenhouseContainer
    ) {
      this.scrollDone = true
      window.scrollTo({
        top: this.greenhouseContainer.offsetTop,
        behavior: `smooth`,
      })
    }

如果遇到类似问题,请查看此包:https ://openbase.io/js/v8-to-istanbul/documentation#ignoring-the-next-line

此外,我找到了一种测试方法,该方法使用andscript附加到 DOM 上:componentDidMount@testing-library/reactjest

  it(`adds script to body`, async () => {
    render(<CareersWithProvider />)
    const Grnhse = await waitFor(() => screen.findAllByTestId(`Grnhse`))
    expect(Grnhse).not.toBeNull()
  })

推荐阅读