在开玩笑中获取原始实施

发布于 2025-02-01 07:49:52 字数 1070 浏览 4 评论 0 原文

我试图在ESM模块中暂时模拟Node-fetch,同时仍在重新审进原始实现,以便我可以访问真实的端点值。但是,此错误“必须使用导入来加载ES模块”。我认识到对ESM的嘲笑支持仍在待处理中 - 是否有任何方法可以结合当前节点,ES6和Jest的组合?

worker.ts(依赖项):

export default async () => {
    const response = await fetch("http://example2.org");
    return await response.json()
  }

main.test.ts:

import { jest } from "@jest/globals";


jest.mock("node-fetch", () => {
    return Promise.resolve({
        json: () => Promise.resolve({ myItem: "abc" }),
    })
})

import doWork from './worker.js';
import mockedFetch from 'node-fetch';

const originalFetch = jest.requireActual('node-fetch') as any;

test("Ensure mock", async () => {
    const result = await doWork();
    expect(result.myItem).toStrictEqual("abc");
    expect(mockedFetch).toBeCalledTimes(1);

    const response = await originalFetch("http://www.example.org");
    expect(response.status).toBe(200);

    const result2 = await doWork();
    expect(result2.myItem).toStrictEqual("abc");
    expect(mockedFetch).toBeCalledTimes(2);
});

I'm trying to temporarily mock node-fetch in an ESM module while still retraining the original implementation so I can access a real endpoint's value. However, this errors with "Must use import to load ES Module." I recognize jest support for ESM is still pending - is there any way to have this behavior in a combination of current Node, ES6, and Jest?

worker.ts (dependency):

export default async () => {
    const response = await fetch("http://example2.org");
    return await response.json()
  }

main.test.ts:

import { jest } from "@jest/globals";


jest.mock("node-fetch", () => {
    return Promise.resolve({
        json: () => Promise.resolve({ myItem: "abc" }),
    })
})

import doWork from './worker.js';
import mockedFetch from 'node-fetch';

const originalFetch = jest.requireActual('node-fetch') as any;

test("Ensure mock", async () => {
    const result = await doWork();
    expect(result.myItem).toStrictEqual("abc");
    expect(mockedFetch).toBeCalledTimes(1);

    const response = await originalFetch("http://www.example.org");
    expect(response.status).toBe(200);

    const result2 = await doWork();
    expect(result2.myItem).toStrictEqual("abc");
    expect(mockedFetch).toBeCalledTimes(2);
});

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

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

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

找个人就嫁了吧 2025-02-08 07:49:52

首先,jest 不支持 jest.jest.mock 在ESM 测试模块

请注意,我们目前不以干净的方式支持jest.mock
在ESM中,但这是我们打算为IN增加适当的支持
未来。遵循此问题以获取更新。

这是合理的,因为导入的语义与需要不同。所有导入均已提升,并将在任何模块代码之前在模块负载上进行评估。

因此,在您的情况下,因为您使用的是 jest.mock 我认为您的测试代码已转换。在这种情况下,如果要使用非“ commonjs”软件包,则也应该对其进行更改。您可以在开玩笑的配置中更改 transformignorepatterns [] 。这意味着来自 node_modules 的所有软件包都将通过变换。如果它太激进了,您可以选择像“ transformignorepatterns”那样忽略的特定模块:[“ node_modules/(?!!(node-fetch))”] ,但不要忘记传递依赖性。 ;)

  • 添加/更改Jest Config
  "transformIgnorePatterns": []
  • Jest.mock接受模块工厂,该工厂应返回导出的代码。就您而言,您应该这样写。
jest.mock("node-fetch", () => {
  return {
    __esModule: true,
    default: jest.fn(() =>
      Promise.resolve({
        json: () => Promise.resolve({ myItem: "abc" }),
      })
    ),
  };
});

如果您有错误

不允许jest.mock()的模块工厂参考任何范围内变量

jest.mock (
https://github.com.com/facebook/jestbook/jest/jest/issues/issues/2567

  • 更改<代码> const Originalfetch = jest.requireactual('node-fetch') to
const originalFetch = jest.requireActual('node-fetch').default;

First, Jest doesn't support jest.mock in ESM module for tests

Please note that we currently don't support jest.mock in a clean way
in ESM, but that is something we intend to add proper support for in
the future. Follow this issue for updates.

This is reasonable because import has different semantic than require. All imports are hoisted and will be evaluated at module load before any module code.

So in your case because you are using jest.mock I assume that your test code are transformed. In this case, if you want to use non "CommonJS" package, you should transform it too. You can change transformIgnorePatterns in jest config to []. It means that all packages from node_modules will go through transform. If it's too aggressive, you can pick specific modules which ignore like this "transformIgnorePatterns": [ "node_modules/(?!(node-fetch))" ] but don't forget about transitive dependencies. ;)

  • Add/change in jest config
  "transformIgnorePatterns": []
  • jest.mock accept module factory which should returns exported code. In your case, you should write it like this.
jest.mock("node-fetch", () => {
  return {
    __esModule: true,
    default: jest.fn(() =>
      Promise.resolve({
        json: () => Promise.resolve({ myItem: "abc" }),
      })
    ),
  };
});

If you have error

The module factory of jest.mock() is not allowed to reference any out-of-scope variables

just remove jest from import and use it as global variable or import it inside the module factory function
https://github.com/facebook/jest/issues/2567

  • Change const originalFetch = jest.requireActual('node-fetch') to
const originalFetch = jest.requireActual('node-fetch').default;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文