无法在 React 中忽略块 Class 带有 istanbul 的组件忽略旁边以获得覆盖

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

我试过在 componentDidMountcomponentDidUpdate 之前使用 /* istanbul ignore next */,就在生命周期定义内,函数名称和括号之间,在 if 块之前生命周期。我也试过使用 /* istanbul ignore if */.

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

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

careers.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`,
      })
    }
  }  

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

在 Jest 版本 26.0 的 jest.config.js 中,您可以将 coverageProvider 配置为 babel(默认)或 v8(考虑为实验性)。

我改成v8安装了v8-to-istanbul:

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

这提供了一些看起来很有效的新功能。除了 functions 之外,我立即获得了 100% 的覆盖率。

    /* 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

此外,我找到了一种方法来测试 script 是否附加到 componentDidMount 上的 DOM 以及 @testing-library/reactjest

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