如何在 Jest 测试中真正调用 fetch

hal*_*onj 5 javascript asynchronous jestjs react-native

有没有办法调用fetchJest 测试?我只想调用实时 API 以确保它仍在工作。如果有 500 个错误或数据不是我所期望的,那么测试应该报告。

我注意到requesthttp模块中使用不起作用。调用fetch,就像我通常在不用于测试的代码中所做的那样,将给出错误:Timeout - Async callback was not invoked within the 5000ms timeout specified by jest.setTimeout.当我在浏览器中调用 API 时,它会在不到一秒的时间内返回。我使用大约以下内容来进行测试,但我也只是fetch从测试中返回了该函数,而没有使用done类似的失败:

import { JestEnvironment } from "@jest/environment";
import 'isomorphic-fetch';
import { request, } from "http";
jest.mock('../MY-API');

describe('tests of score structuring and display', () => {
    test('call API - happy path', (done) => {
        fetch(API).then(
            res => res.json()
        ).then(res => {
            expect(Array.isArray(response)).toBe(true);
            console.log(`success: ${success}`);
            done();
        }).catch(reason => {
            console.log(`reason: ${reason}`);
            expect(reason).not.toBeTruthy();
            done();
        });
    });
});
Run Code Online (Sandbox Code Playgroud)

奇怪的是,在达到超时后,我可以看到一条错误消息作为控制台消息: reason: ReferenceError: XMLHttpRequest is not defined

如何在 Jest 测试中对实时 API 进行实际调用,而不是模拟调用?这简直是​​被禁止了吗?根据文档,我不明白为什么这会失败,所以我怀疑在 React-Native 中隐式导入的某些东西必须在 Jest 测试中显式导入才能使fetchorrequest函数工作。

Bri*_*ams 7

搁置关于在单元测试中进行实际网络调用是否是最佳实践的任何讨论......

没有理由为什么你不能做到这一点。

这是一个从JSONPlaceholder中提取数据的简单工作示例:

import 'isomorphic-fetch';

test('real fetch call', async () => {
  const res = await fetch('https://jsonplaceholder.typicode.com/users/1');
  const result = await res.json();
  expect(result.name).toBe('Leanne Graham');  // Success!
});
Run Code Online (Sandbox Code Playgroud)

所有的工作Jest都在幕后完成(定义全局变量,如describe, beforeAll,test等,将代码文件路由到转译器,处理模块缓存和模拟等)最终实际的测试只是 JavaScript 代码,并且Jest只运行它找到的任何 JavaScript 代码,因此,您可以在单元测试中运行的内容确实没有任何限制。

  • 对于任何想要调用本身使用 fetch 的代码的人,我发现以下建议有助于模拟 fetch 函数本身:`global.fetch = fetch`,其中 fetch 是导入的 fetch 函数。 (2认同)