Express、Jest 和 Supertest 出现随机 Axios 错误

问题描述 投票:0回答:1

我在测试 Express 端点时遇到 Supertest 问题,它会随机失败,通常会出现

AxiosError: Request failed with status code 404
错误,没有有用的堆栈跟踪。

该错误每次都发生在随机文件上。如果我直接运行该文件的测试,它们都会很好地通过,任何测试实际上都没有问题,直接运行时它们都会通过。

问题出在运行全套测试时(大约 40 个文件中的大约 280 个测试)。总是会出现至少一个,有时甚至更多相同的错误:

  ● Test suite failed to run

    AxiosError: Request failed with status code 404

      at settle (node_modules/axios/lib/core/settle.js:19:12)
      at IncomingMessage.handleStreamEnd (node_modules/axios/lib/adapters/http.js:599:11)
      at Axios.request (node_modules/axios/lib/core/Axios.js:45:41)

该错误似乎与文件中的测试完全无关。有时,失败的测试文件是纯单元测试,不执行任何类型的 HTTP 请求,甚至不使用 Axios 导入任何内容,但它会抛出相同的 Axios 错误。

我通过 Supertest 发现了这个问题。我重构了所有测试以使用这个新的启动和关闭程序,但它什么也没做。

另一个可能有用的信息是,错误总是发生在整个套件运行的一半到 3/4 左右。它永远不会立即发生,并且总是在不同的测试文件上。

我如何才能提供更多信息来调试它?不可能知道它发生在哪里,因为它的失败测试实际上与错误无关。我什至无法展示失败测试的示例,因为它们在单独运行时都通过了。

我所有的测试都遵循这个模式:

const request = supertest(app);


describe("functionName", () => {
    it("should perform x", async () => {
      const res = await request.get("/v1/asset");
      const { result } = res.body;
      expect(res.status).toEqual(200);
      // etc etc
    });
});

app
的示例:

import express from "express";

const app = express();
        app.get("/routes", (req, res) => {
            res.json({});
        });

export default app;

运行:Node 20.16、Yarn 4.4.0、Jest 29.7.0、Supertest 6.3.4

express jestjs supertest
1个回答
0
投票

如果其他人遇到类似的问题,请在这里回答我自己的问题,因为这是一个很难解决的问题。

如上所述,该错误是 Axios 抛出的关于某些 404 响应的通用异常。 它在随机测试中看似随机的时间发生,甚至没有执行 Axios 请求。

堆栈跟踪没有帮助,错误没有提供任何有用的信息(我们的应用程序中有数百个 axios 调用,是哪一个?)。

我能够通过在

jest.config.js

中配置设置JS文件来调试错误源
    setupFilesAfterEnv: ["./tests/setupJest.ts"]

此文件在所有测试之前运行。

在这个文件中,我配置了一个 Axios 拦截器来拦截 Axios 响应和错误响应,以便您可以注销有关请求、URL、方法等的信息。

axios.interceptors.response.use(
  (response) => {
    // Any status code that lie within the range of 2xx cause this function to trigger
    // Do something with response data
    return response;
  },
  async (error) => {
    // Any status codes that falls outside the range of 2xx cause this function to trigger
    // Do something with response error
    console.log("AXIOS DEBUG", error.request.method, error.request.path, error.response.status, error.stack);
    return Promise.reject(error);
  }
);

现在,当我在控制台中运行测试套件时,在这个神秘的 404 错误所在的位置,我可以看到请求路径和方法已注销,在我的例子中,这是对外部端点的 DELETE 请求,基本上是删除操作。

这显着缩小了潜在的罪魁祸首代码的范围。

我审查了执行此操作的所有测试,果然我发现了一个未

await
ed 的 Axios 删除请求,因此它正在运行并导致请求失败,但此时另一个测试已开始。

向这一行添加一个等待,解决了问题,但如果没有这一点信息,我永远不会在我们超过 100 万行的代码库中找到这一行代码。

希望能帮助别人摆脱沮丧的日子。

© www.soinside.com 2019 - 2024. All rights reserved.