【问题标题】:JEST throws .finally is not a functionJEST 抛出 .finally 不是函数
【发布时间】:2025-12-01 22:20:03
【问题描述】:

这是我的反应组件:

import { sendAnalytics } from 'analytics';

class MyComponent extends React.Component {
    myMethod() {
        console.log('do something!');
    }

    render() {
        return (
            <Button 
                onClick={submitAnalytics({name: 'foo'}).finally(this.myMethod())} 
                dataset={{"data-id": "button"}}
            > Send Analytics
            </Button>
            }
        )
    }
}

而我的测试是这样的:

import * as analytics from 'analytics';
jest.mock('analytics');

describe('Analytics', () => {
    it('Should call analytics when button is clicked', () => {
        analytics.submitAnalytics.mockResolvedValue(Promise.resolve(true));
        const tree = ReactTestRenderer.create(<MyComponent />);

        // Actual implementation of following 3 lines is slightly different.
        const button = tree.root.findByProps({"data-id": "button"});
        button.props.onClick();
        expect(analytics.submitAnalytics).toHaveBeenCalled();
    });
});

我尝试了几种不同的模拟策略,例如:

analytics.submitAnalytics.mockImplementation(() => {
    return Promise.resolve(true)
});

似乎没有任何结果。我不断收到以下错误:

TypeError: (0 , analytics.submitAnalytics)(...).finally is not a function.

我不知道为什么。任何帮助表示赞赏。 如果您需要更多上下文代码,请告诉我。

【问题讨论】:

  • 您是否尝试过返回一个新的 Promise 而不是返回 resolve 方法的结果?
  • 是的,我做到了。

标签: javascript reactjs jestjs


【解决方案1】:

在测试前导入@babel/polyfill也可以解决这个问题

import '@babel/polyfill';

// Your tests...

【讨论】:

    【解决方案2】:

    升级我的节点版本

    v8.10.0

    v10.19.0

    解决了这个错误。

    查看MDN 上的浏览​​器兼容性图表,在10.0.0 之前,Node 似乎不支持 .finally()

    【讨论】:

      【解决方案3】:

      import '@babel/polyfill'; 为我工作,但自 babel 7.4 起已弃用。

      相反,导入它也可以正常工作:

      import "core-js/stable";
      import "regenerator-runtime/runtime";
      

      最后,我刚刚更新了节点版本(从 8.10.2 到 12.16.1)

      【讨论】:

        【解决方案4】:

        伙计们,我想通了!以下是要做的事情:

        analytics.submitPayload = jest.fn().mockImplementation(() => {
          return {
            finally: () => {
              return true;
            }
          };
        });
        

        我不知道这是对还是错,但它确实有效。如果有更好的方法,请告诉我。

        【讨论】:

          【解决方案5】:

          我也面临同样的挑战。 原因 - Jest 在 Node 环境中运行,并且 Node 版本支持“Finally” - 10.0.0。 但是我的 Jenkins 版本是 8.x,所以作为一个快速修复你可以从代码中最终删除。稍后我们可以升级本地和远程服务器版本。

          以下是 MDN 链接- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/finally

          【讨论】: