在 Express 中测试中间件而不创建重新创建服务器的简单方法?

rb6*_*612 1 javascript mocha.js node.js sinon

我希望能够在每次测试的基础上存根我的中间件功能。正如此处阐明的,问题是我不能仅仅存根我的中间件函数,因为节点已经缓存了中间件函数,所以我不能存根它,因为我在一开始创建了我的应用程序。

const request = require("supertest");
const { expect } = require("chai");
const sinon = require('sinon');
const auth = require ("../utils/auth-middleware")
const adminStub = sinon.stub(auth, "isAdmin").callsFake((req, res, next) => next());
const app = require("../app.js"); // As soon as I create this, the middleware isAdmin function becomes cached and no longer mutable
Run Code Online (Sandbox Code Playgroud)

以上作为链接的SO答案中描述的解决方案,但我不喜欢那样为了恢复存根或修改假,我必须完全重新创建服务器。

我想知道是否有更好、更优雅的方法来解决 Node 首先缓存这些函数的事实require。我正在研究可能使用proxyquireordecache但两者似乎都提供了解决方法而不是可持续的解决方案(尽管我很可能在这里错了)。

Ser*_*pin 7

问题与 Node 缓存模块并没有真正的关系——它表示在最初创建服务器时谁存储了对中间件函数的引用。在d 模块的isAdmin方法require被存根后,缓存版本被存根,因此使用类似的工具proxyquire只会允许您在出于某种原因需要模块的新版本(没有存根方法)时需要它。

如果您正在寻找的是为已创建的快速服务器调整特定中间件的行为,则您需要一种方法来通过其引用来改变中间件功能的行为。希望 sinon 存根(以及其他存根,例如 jest 提供的存根)能够做到这一点。但是,您仍然需要在创建快速服务器之前存根模块,以便它存储对存根函数的引用。

示例实现可能如下所示:

const request = require("supertest");
const { expect } = require("chai");
const sinon = require('sinon');
const auth = require ("../utils/auth-middleware");

// store reference to original function in case you need it:
const originalIsAdmin = auth.isAdmin

// replace isAdmin method with a stubbed, but don't specify implementation yet
const adminStub = sinon.stub(auth, "isAdmin");

// init express server that relies on stubbed `auth.isAdmin` reference
const app = require("../app.js");

it('this test is using auth.isAdmin that just calls .next()', () => {
  // make middleware just pass
  auth.isAdmin.callsFake((req, res, next) => next());

  // ...
});

it('this test is using real auth.isAdmin implementation', () => {
  // make middleware call real implementation
  auth.isAdmin.callsFake(originalIsAdmin);

  // ...
});
Run Code Online (Sandbox Code Playgroud)