针对未处理的 Supertest 请求的 MSW 日志记录警告

Posted

技术标签:

【中文标题】针对未处理的 Supertest 请求的 MSW 日志记录警告【英文标题】:MSW logging warnings for unhandled Supertest requests 【发布时间】:2021-09-02 14:06:16 【问题描述】:

在我使用 Supertest 和 MSW 进行的测试中,我注意到,尽管它们仍然成功通过,但 MSW 已经开始针对 Supertest 发出的请求显示警告。例如(见文末复现文件):

$ npm t

> msw-example@1.0.0 test
> jest

 PASS  ./app.test.js
  password API
    ✓ exposes a number of words (76 ms)

  console.warn
    [MSW] Warning: captured a request without a matching request handler:

      • GET http://127.0.0.1:55984/api

    If you still wish to intercept this unhandled request, please create a request handler for it.
    Read more: @987654321@

      at onUnhandledRequest (node_modules/msw/node/lib/index.js:7599:21)
      at node_modules/msw/node/lib/index.js:7630:13
      at fulfilled (node_modules/msw/node/lib/index.js:50:58)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        1.005 s
Ran all test suites.

GET http://127.0.0.1:55984/api 的请求是 Supertest 向应用发出的请求,这是测试的重点,而不是 MSW 需要处理的请求。我第一次编写测试时也没有显示这些警告。

链接页面显示了如何创建处理程序,但我不希望 MSW 处理这些请求。为什么会出现这种情况,我该如何阻止它显示"/api" 调用的警告?


package.json:


  "name": "msw-example",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": 
    "test": "jest"
  ,
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": 
    "axios": "^0.21.1",
    "express": "^4.17.1"
  ,
  "devDependencies": 
    "jest": "^27.0.4",
    "msw": "^0.29.0",
    "supertest": "^6.1.3"
  

app.js:

const axios = require("axios");
const express = require("express");

const app = express();

app.get("/api", (_, res) => 
  axios.get("https://api.pwnedpasswords.com/range/ABC12")
    .then(() => res.json( words: 3 ))
    .catch((err) => res.sendStatus(500));
);

module.exports = app;

app.test.js:

const  rest  = require("msw");
const  setupServer  = require("msw/node");
const request = require("supertest");

const app = require("./app");

const server = setupServer(
  rest.get("https://api.pwnedpasswords.com/range/:range", (req, res, ctx) => 
    return res(ctx.status(200), ctx.text(""));
  ),
);

describe("password API", () => 
  beforeAll(() => server.listen());

  beforeEach(() => server.resetHandlers());

  afterAll(() => server.close());

  it("exposes a number of words", () => 
    return request(app).get("/api").expect(200).then((res) => 
      expect(res.body.words).toBe(3);
    );
  );
);

【问题讨论】:

【参考方案1】:

此功能在 MSW v0.20.0 中引入,但在 v0.29.0 中,未处理请求的默认设置从 "bypass" 更改为 "warn",因此控制台中突然出现警告。您可以将其重置为"bypass",如setupWorker#startsetupServer#listen 的文档中所示,在我的情况下:

beforeAll(() => server.listen( onUnhandledRequest: "bypass" ));

但是,这可能意味着您应该处理的请求缺少警告,因此另一种选择是传递一个接收请求对象的函数。这可以例如记录警告或抛出错误(这将导致测试失败)。就我而言,由于我所有的 Supertest 请求都是针对 /api 端点的,因此看起来像:

beforeAll(() => server.listen( 
  onUnhandledRequest: ( method, url ) => 
    if (!url.pathname.startsWith("/api")) 
      throw new Error(`Unhandled $method request to $url`);
    
  ,
));

正如kettanaito 在 cmets 中所建议的那样,我调查了您是否可以通过它们的标题识别 Supertest 调用。不幸的是,Supertest no longer 似乎设置了默认 User-Agent,所以你必须逐个测试:

describe("password API", () => 
  beforeAll(() => server.listen( 
    onUnhandledRequest: ( headers, method, url ) => 
      if (headers.get("User-Agent") !== "supertest") 
        throw new Error(`Unhandled $method request to $url`);
      
    ,
  ));

  beforeEach(() => server.resetHandlers());

  afterAll(() => server.close());

  it("exposes a number of words", () => 
    return request(app)
      .get("/api")
      .set("User-Agent", "supertest")
      .expect(200)
      .then((res) => 
        expect(res.body.words).toBe(3);
      );
  );
);

【讨论】:

如果 Supertest 附加任何自定义请求标头,可以让您更可靠地确定 Supertest 发出的请求,值得探索。 @kettanaito 好主意!看起来 Superagent no longer 设置了默认的 User-Agent,但我必须在所有测试中都这样做。

以上是关于针对未处理的 Supertest 请求的 MSW 日志记录警告的主要内容,如果未能解决你的问题,请参考以下文章

使用 MSW 和 Jest 时如何在请求之间的测试中清除 RTK 查询缓存?

如何使用 supertest 和 agent 在 mocha 测试中发出经过身份验证的请求?

MongoMemoryServer ;未处理的错误

如何使用 msw 有条件地模拟错误响应

使用 mocha 测试 express 服务器并使用异步初始化程序进行 supertest 调用请求两次

如何将 Service Worker 库 (MSW) 与 Parcel 捆绑器一起使用