React测试库:在React Hook中加载的脚本的测试ONLOAD回调

发布于 2025-02-09 20:23:51 字数 2535 浏览 0 评论 0原文

我正在编写一个库来支持支持Google身份服务的库。使用Google登录,需要将脚本加载到文档中的脚本标签中。此脚本不作为软件包可用。我将脚本标签添加到文档头中的react Hook,该钩子通过OnloadOnError回调。我需要测试当脚本加载或不成功加载时调用这些回调。不幸的是,在我的测试中,两个回调都被召唤,我不知道为什么。

这是React Hook调用的功能,以将< script>标记在文档头部:

const loadGapiScript = (document, src, onLoad, onError) => {
  const script = document.getElementsByTagName('script')[0]

  let js = document.createElement('script')
  js.id = 'google-auth'
  js.src = src
  js.async = true
  js.defer = true

  js.onerror = onError
  js.onload = onLoad

  if (script && script.parentNode) {
    script.parentNode.insertBefore(js, script)
  } else {
    document.head.appendChild(js)
  }
}

这是我的测试代码:

import { renderHook, waitFor } from '@testing-library/react'
import useGoogleLogin from './use-google-login'

describe('useGoogleLogin', () => {
  const clientId = 'somestring'
  const onLoad = jest.fn(() => {})

  it('calls the onLoad callback', async () => {
    renderHook(() => useGoogleLogin({ clientId, onLoad }))

    await waitFor(() => expect(onLoad).toHaveBeenCalled())
  })
})

这是我运行测试时的输出:

    expect(jest.fn()).toHaveBeenCalled()

    Expected number of calls: >= 1
    Received number of calls:    0

    Ignored nodes: comments, <script />, <style />
    <html>
      <head />
      <body>
        <div />
      </body>
    </html>

      30 |               renderHook(() => useGoogleLogin({ clientId, onLoad }))
      31 |
    > 32 |               await waitFor(() => { expect(onLoad).toHaveBeenCalled() })
         |                                                       ^
      33 |             })
      34 |           })
      35 |         })

      at toHaveBeenCalled (__tests__/use-google-login-test.js:32:55)
      at runWithExpensiveErrorDiagnosticsDisabled (node_modules/@testing-library/dom/dist/config.js:50:12)
      at checkCallback (node_modules/@testing-library/dom/dist/wait-for.js:141:77)
      at checkRealTimersCallback (node_modules/@testing-library/dom/dist/wait-for.js:133:16)
      at Timeout.task [as _onTimeout] (node_modules/jsdom/lib/jsdom/browser/Window.js:514:19)

我怀疑问题可能与&lt; script&gt;节点被忽略的事实有关,但是我不确定如何更改它,因为唯一的文档是模糊的,并参考filternode函数传递到prettydom中,我不使用它(至少没有明确)。这些文档也在打字稿中,因为我不知道打字稿,这使事情变得更加复杂。

策略性放置的控制台记录表明,整个loadGapiscript函数确实在测试过程中运行。

I'm writing a library for React supporting Google identity services. Sign In With Google requires a script be loaded in a script tag in the document. This script is not available as a package. I'm adding the script tag to the document head in a React hook that passes in onload and onerror callbacks. I need to test that these callbacks are being called when the script loads or doesn't load successfully. Unfortunately, in my tests, neither callback is called and I don't know why.

This is the function that the React hook calls to add the <script> tag to the document head:

const loadGapiScript = (document, src, onLoad, onError) => {
  const script = document.getElementsByTagName('script')[0]

  let js = document.createElement('script')
  js.id = 'google-auth'
  js.src = src
  js.async = true
  js.defer = true

  js.onerror = onError
  js.onload = onLoad

  if (script && script.parentNode) {
    script.parentNode.insertBefore(js, script)
  } else {
    document.head.appendChild(js)
  }
}

And this is my test code:

import { renderHook, waitFor } from '@testing-library/react'
import useGoogleLogin from './use-google-login'

describe('useGoogleLogin', () => {
  const clientId = 'somestring'
  const onLoad = jest.fn(() => {})

  it('calls the onLoad callback', async () => {
    renderHook(() => useGoogleLogin({ clientId, onLoad }))

    await waitFor(() => expect(onLoad).toHaveBeenCalled())
  })
})

This is the output when I run the test:

    expect(jest.fn()).toHaveBeenCalled()

    Expected number of calls: >= 1
    Received number of calls:    0

    Ignored nodes: comments, <script />, <style />
    <html>
      <head />
      <body>
        <div />
      </body>
    </html>

      30 |               renderHook(() => useGoogleLogin({ clientId, onLoad }))
      31 |
    > 32 |               await waitFor(() => { expect(onLoad).toHaveBeenCalled() })
         |                                                       ^
      33 |             })
      34 |           })
      35 |         })

      at toHaveBeenCalled (__tests__/use-google-login-test.js:32:55)
      at runWithExpensiveErrorDiagnosticsDisabled (node_modules/@testing-library/dom/dist/config.js:50:12)
      at checkCallback (node_modules/@testing-library/dom/dist/wait-for.js:141:77)
      at checkRealTimersCallback (node_modules/@testing-library/dom/dist/wait-for.js:133:16)
      at Timeout.task [as _onTimeout] (node_modules/jsdom/lib/jsdom/browser/Window.js:514:19)

I suspect the issue may have to do with the fact that <script> nodes are ignored, but I'm not sure how to change this as the only docs are vague and refer to a filterNode function passed into PrettyDOM, which I'm not using (at least not explicitly). The docs are also in TypeScript, which complicates things further since I don't know TypeScript.

Strategically placed console logging reveals that the entire loadGapiScript function does run in the course of the test.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文