在 React 组件中调用内部函数

Posted

技术标签:

【中文标题】在 React 组件中调用内部函数【英文标题】:Call an internal function in React component 【发布时间】:2022-01-24 04:48:59 【问题描述】:

这个组件实现了 google recaptcha。这不是整个实现,但这是相似的。 我正在尝试测试是否调用了 onSuccess 回调函数。

function ReCaptcha() 
  function onSuccess() 
    console.log("we are sucessful");
  
  useEffect(() => 
    window.grecaptcha = 
      enterprise: ,
    ;
    window.grecaptcha.enterprise = 
      execute: function (onSuccess) 
        //this part is done with google and it calls back onSuccess
      ,
    ;
    window.grecaptcha.enterprise.execute().then(() => 
      onSuccess();
    );
  , []);
  return <h1>ReCaptcha</h1>;


export default ReCaptcha;

我根据这篇文章多次尝试调用这个函数,但都没有成功。

理想情况下,我想模拟 onSuccess 并查看是否已被调用。

onSuccess = jest.fn()
expect(onSuccess).toHaveBeenCalled();

【问题讨论】:

【参考方案1】:

您不能模拟 onSuccess 函数。它是在功能范围内定义的,它是私有的。 如果你不能访问它,你就不能模拟或窥探它

您可以监视console.log 方法。如果被调用,则间接表示调用了onSuccess。只是console.log 没有多大意义,这只是一个演示。

例如

index.tsx:

//@ts-nocheck
import React from 'react';
import  useEffect  from 'react';

export default function ReCaptcha() 
  function onSuccess() 
    console.log('we are sucessful');
  
  useEffect(() => 
    window.grecaptcha = 
      enterprise: ,
    ;
    window.grecaptcha.enterprise = 
      execute: function () 
        return new Promise((resolve) => 
          resolve();
        );
      ,
    ;
    window.grecaptcha.enterprise.execute().then(() => 
      onSuccess();
    );
  , []);
  return <h1>ReCaptcha</h1>;

index.test.tsx:

import  render, waitFor  from '@testing-library/react';
import React from 'react';
import ReCaptcha from './';

describe('ReCaptcha', () => 
  test('should pass', async () => 
    const logSpy = jest.spyOn(console, 'log');
    render(<ReCaptcha />);
    await waitFor(() => expect(logSpy).toBeCalledWith('we are sucessful'));
  );
);

测试结果:

 PASS  examples/70457908/index.test.tsx (10.199 s)
  ReCaptcha
    ✓ should pass (75 ms)

  console.log
    we are sucessful

      at console.<anonymous> (node_modules/jest-mock/build/index.js:845:25)

-----------|---------|----------|---------|---------|-------------------
File       | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-----------|---------|----------|---------|---------|-------------------
All files  |     100 |      100 |     100 |     100 |                   
 index.tsx |     100 |      100 |     100 |     100 |                   
-----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        11.334 s

【讨论】:

您好,感谢您的回答。我已经编辑了问题以使其更清楚。基本上,回调是我无法控制的。当用户成功时,Google recaptcha 脚本会回调它,因此在我的测试中,永远不会调用 onSuccess。

以上是关于在 React 组件中调用内部函数的主要内容,如果未能解决你的问题,请参考以下文章

React 组件模块(从本地 repo 导入)导致错误“只能在函数组件的主体内部调用 Hooks。”

无效的挂钩调用。钩子只能在使用 react-apollo 的函数组件内部调用

React - 错误:无效的钩子调用。 Hooks 只能在函数组件的主体内部调用

React Native 错误:无效的钩子调用。 Hooks 只能在函数组件的主体内部调用

React + Antd + Rollup 组件库“错误:无效的钩子调用。钩子只能在函数组件的主体内部调用”

React 17 - 添加 Evergreen UI 窗格会导致错误:无效的挂钩调用。 Hooks 只能在函数组件的主体内部调用