在node.js ESM中我想存根一个导出的模块,这是默认的

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

我有一个非常简单的身份验证中间件,带有

export default ()
匿名函数:

export default () => async (req, res, next) => {
  try {
       // some auth implementation... does not matter
    } else {
      throw new Error('No "Bearer" token passed as header')
    }

    next()
  } catch (err) {
    next(err)
  }
}

我想在我的单元测试中存根它以继续

next()

import express from 'express';
import supertest from 'supertest';
import { router } from "express-file-routing"
import auth from '../../middlewares/auth.js';
import sinon from 'sinon'

describe("/foo", () => {
    let app, request;
    
    before(async () => {
        app = express();
        app.use("/", await router())
        request = supertest(app);
    });

    beforeEach(() => {
   
        sinon.stub(auth()).callsFake((req, res, next) => next());
        // tried also ...
        // sinon.replace(auth, 'default', () => (req, res, next) => next());
});
//... test continue

但是这些都不起作用。我越来越

TypeError: sinon.stub(...).callsFake is not a function
或者
 TypeError: Cannot replace non-existent property default. Perhaps you meant sandbox.define()?
当我尝试使用
sinon.replace

javascript node.js unit-testing es6-modules sinon
1个回答
0
投票

正如 @Estus Flask 提到的,ES 模块有一个不可变的命名空间。这基本上意味着您无法分配/覆盖导出。您可以做的是使用模块加载器,如 Sinon 文章中所述

如果使用 Quibble,生成的代码如下所示:

describe("main module", () => {
  let mocked, main;

  before(() => {
    mocked = sinon.fake.returns("mocked");
    quibble("./other", { toBeMocked: mocked });
    ({ main } = require("./main"));
  });

  it("should mock", () => {
    main();
    expect(mocked.called).to.be.true;
  });
});

完整的工作示例:https://github.com/fatso83/sinon-swc-bug/tree/esm-no-ts

Mocha 的重要一点是在

.mocharc.json
中指定加载器:

{
  "spec": [
    "src/**/*.{spec,test}.js"
  ],
  "loader": "quibble"
}
© www.soinside.com 2019 - 2024. All rights reserved.