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定位。
解决步骤
- 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); }) } } };
确保组件能获取到google变量
在customRender时,确保组件能接收到google参数(比如通过Wrapper传递或上下文注入),这样useEffect的条件判断google && divRef.current才能成立,触发初始化函数。修正useEffect依赖数组(可选但推荐)
原代码中useEffect依赖divRef.current会导致不必要的重复执行,且React会抛出警告,建议修改为依赖google即可:
useEffect(() => { if (google && divRef.current) { initialiseGoogle(handleCallbackResponse, google); } }, [google]); // 移除divRef.current,ref对象本身是稳定的
完成以上操作后,测试中的findByTitle就能定位到Mock生成的Google登录按钮,测试即可通过。
内容的提问来源于stack exchange,提问作者userWantsToCode
相关产品推荐
相关产品推荐

