【问题标题】:How to really call fetch in Jest test如何在 Jest 测试中真正调用 fetch
【发布时间】:2019-08-25 04:35:42
【问题描述】:

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

我注意到使用 http 模块中的 request 不起作用。调用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();
        });
    });
});

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

如何在 Jest 测试中对实时 API 进行实际调用,而不是模拟调用?这只是被禁止了吗?我不明白为什么在给定 documentation 的情况下这会失败,所以我怀疑在 React-Native 中隐式导入了一些必须在 Jest 测试中显式导入才能使 fetchrequest 函数工作的东西。

【问题讨论】:

  • 我认为您的方法不正确。在您的单元测试中,您不需要检查服务是否处于活动状态,您应该模拟调用并测试您的处理程序是否成功/失败,您不需要执行真正的 API 调用来实现这一点
  • @Jony-Y,假设我已经疯到想要检查服务是否还活着。这甚至允许吗?
  • 理论上一切都是允许的,但听起来它不应该在你的测试范围内。您需要测试您的逻辑以及如何处理更改。不是服务或 3rd 方包,它们有自己的测试。
  • @Jony-Y,我并不强烈反对。我正在尝试测试通常不在移动应用程序的适当测试范围内考虑的东西。但是,我该怎么做呢?
  • @Jony-Y 集成/功能测试没有错。我同意单元测试应该被隔离,但是功能测试是有时间和地点的。话虽如此,为了使用 WebAPI,您需要在浏览器环境中运行测试。或者,您可以尝试在测试开始之前将fetch polyfill(如node-fetch)分配给global 对象。

标签: javascript react-native asynchronous jestjs


【解决方案1】:

暂且不论关于在单元测试中进行实际网络调用是否是最佳实践的讨论...

你没有理由不能这样做。

这是一个从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!
});

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

【讨论】:

  • 对于任何希望调用本身使用 fetch 的代码的人,我发现该建议有助于模拟 fetch 函数本身:global.fetch = fetch 其中 fetch 是您导入的 fetch 函数。
猜你喜欢
  • 2022-01-26
  • 2017-10-17
  • 2018-01-29
  • 2022-01-23
  • 1970-01-01
  • 2018-04-25
  • 2019-12-22
  • 1970-01-01
  • 2016-01-19
相关资源
最近更新 更多