You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React测试Google身份服务登录按钮:查询时无法找到按钮

React中Google登录按钮测试无法定位问题:是否需要Mock谷歌API?

问题描述

我在React项目中使用Google身份服务实现登录按钮,但运行测试用findByTitle查询时无法定位到该按钮,请问是否需要Mock谷歌API调用?

相关代码及测试信息

按钮初始化函数

export const initialiseGoogle = (callbackResponse, google) => {
 /* global google */
 google.accounts.id.initialize({
   client_id: process.env.REACT_APP_ID,
   callback: callbackResponse,
 });
 window.google.accounts.id.renderButton(
   document.getElementsByClassName("buttonSignIn")[0],
  {
    shape: "circle",
    size: "medium",
    type: "standard",
  }
 );
};

调用初始化函数的useEffect

useEffect(() => {
  // Initializes the google sign-in button
  if (google && divRef.current) {
    console.log(google);
    initialiseGoogle(handleCallbackResponse, google);
  }
}, [google, divRef.current]);

承载按钮的div

<section>
  <div
    ref={divRef}
    className={`buttonSignIn ${signInButtonClass}`}
    hidden={!isSignedIn ? false : true}
  ></div>
</section>

测试代码及失败信息

const user = userEvent.setup();

test("The Google sign-in should be visible within 3sec of page load", async () => {
  const { debug, getByPlaceholderText, getByRole, findByTitle } = customRender(
    Wrapper,
    <App />
    );

  const button = await findByTitle("Sign in with Google Button");

  debug();
});

测试失败结果:

FAIL src/components/__tests__/Header.test.js
 × The Google sign-in should be visible within 3sec of page load (1060 ms)

 ● The Google sign-in should be visible within 3sec of page load

  Unable to find an element with the title: Sign in with Google Button.

Ignored nodes: comments, script, style
<body>
  <div>
    <header>
      <div
        class="w-100 divider-1"
      />
      <div
        class="header-container border-ani container-fluid"
      >
        <div
          class="d-flex full-logo flex-row justify-content-center"
        >
          <i
            class="check square logo-icon outline icon mb-2 "
          />
        </div>
        <div
          class="signIn-div d-flex justify-content-center"
        >
          <section
            class="w-100 d-flex justify-content-center"
          >
            <div
              class="buttonSignIn"
            />
       </header>
      </div>
    </body>

解答

是的,必须Mock谷歌API调用,原因和解决步骤如下:

核心原因

测试环境不会加载真实的Google身份服务脚本,导致window.google不存在,组件中initialiseGoogle函数不会执行,目标div里不会生成Google登录按钮元素,自然无法通过findByTitle定位。

解决步骤

  1. Mock全局google对象
    在测试文件顶部或测试setup文件中添加Mock代码,模拟Google API的初始化和按钮渲染行为:
// Mock Google Identity Services API
global.google = {
  accounts: {
    id: {
      initialize: jest.fn(),
      // 模拟renderButton,手动创建按钮插入目标div
      renderButton: jest.fn((targetElement, options) => {
        const googleButton = document.createElement('button');
        googleButton.title = 'Sign in with Google Button';
        googleButton.textContent = 'Sign in with Google';
        targetElement.appendChild(googleButton);
      })
    }
  }
};
  1. 确保组件能获取到google变量
    在customRender时,确保组件能接收到google参数(比如通过Wrapper传递或上下文注入),这样useEffect的条件判断google && divRef.current才能成立,触发初始化函数。

  2. 修正useEffect依赖数组(可选但推荐)
    原代码中useEffect依赖divRef.current会导致不必要的重复执行,且React会抛出警告,建议修改为依赖google即可:

useEffect(() => {
  if (google && divRef.current) {
    initialiseGoogle(handleCallbackResponse, google);
  }
}, [google]); // 移除divRef.current,ref对象本身是稳定的

完成以上操作后,测试中的findByTitle就能定位到Mock生成的Google登录按钮,测试即可通过。

内容的提问来源于stack exchange,提问作者userWantsToCode

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 23:50:14