首页 > 解决方案 > 无法使用 `fetch-mock-jest 1.5.1` lib 模拟 fetch 调用

问题描述

我正在尝试使用此fetch-mock-jest模拟 fetch 调用,但代码仍尝试转到远程地址并最终失败并显示错误消息FetchError: request to https://some.domain.io/app-config.yaml failed, reason: getaddrinfo ENOTFOUND some.domain.io]

这里是测试代码

import { AppConfig } from '@backstage/config';
import { loadConfig } from './loader';
import mockFs from 'mock-fs';
import fetchMock from 'fetch-mock-jest';

describe('loadConfig', () => {
  beforeEach(() => {
    fetchMock.mock({
      matcher: '*',
      response: `app:
          title: Example App
          sessionKey: 'abc123'
      `
    });
  });

  afterEach(() => {
    fetchMock.mockReset();
  });

  it('load config from remote path', async () => {
    const configUrl = 'https://some.domain.io/app-config.yaml';

    await expect(
       loadConfig({
        configRoot: '/root',
        configTargets: [{ url: configUrl }],
        env: 'production',
        remote: {
          reloadIntervalSeconds: 30,
        },
      })
    ).resolves.toEqual([
      {
        context: configUrl,
        data: {
          app: {
            title: 'Example App',
            sessionKey: 'abc123',
          },
        },
      },
    ]);
    expect(fetchMock).toHaveBeenCalledTimes(1);
  });

  function defer<T>() {
    let resolve: (value: T) => void;
    const promise = new Promise<T>(_resolve => {
      resolve = _resolve;
    });
    return { promise, resolve: resolve! };
  }
});

loadConfig有我试图模拟的获取代码。

export async function loadConfig(
  options: LoadConfigOptions,
): Promise<AppConfig[]> {
  const loadRemoteConfigFiles = async () => {
    const configs: AppConfig[] = [];

    const readConfigFromUrl = async (remoteConfigProp: RemoteConfigProp) => {
      const response = await fetch(remoteConfigProp.url);
      if (!response.ok) {
        throw new Error(
          `Could not read config file at ${remoteConfigProp.url}`,
        );
      }

      remoteConfigProp.oldETag = remoteConfigProp.newETag ?? undefined;
      remoteConfigProp.newETag =
        response.headers.get(HTTP_RESPONSE_HEADER_ETAG) ?? undefined;
      remoteConfigProp.content = await response.text();

      return remoteConfigProp;
    };

.......
    return configs;

}

let remoteConfigs: AppConfig[] = [];
  if (remote) {
    try {
      remoteConfigs = await loadRemoteConfigFiles();
    } catch (error) {
      throw new Error(`Failed to read remote configuration file, ${error}`);
    }
  }

........ do some stuff with config then return
return remoteConfigs;
}

config 是一个 yaml 文件,最终会被解析并转换为 config 对象。

知道为什么它无法模拟 fetch 调用吗?

标签: node.jstypescriptjestjsfetch

解决方案


更换

import fetchMock from 'fetch-mock-jest';

const fetchMock = require('fetch-mock').sandbox();
const nodeFetch = require('node-fetch');
nodeFetch.default = fetchMock;

fetchMock.mockReset();fetchMock.restore();


推荐阅读