You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

测试中间件时触发TypeError: is not a function错误求助

Troubleshooting "TypeError: *** is not a function" in Auth Middleware Test

Let's walk through why you're hitting this error in your auth middleware test, and fix it step by step.

1. You've Misconfigured res.locals

Looking at your test code, you've set res.locals to a sinon spy function:

const res = { locals: sinon.spy() }

But in Express, res.locals is supposed to be a plain JavaScript object for storing request-scoped variables. If your login middleware tries to assign res.locals.token = someToken, it's essentially trying to set a property on a function—which will break things, and could trigger the "not a function" error you're seeing.

Fix this by changing res.locals to an empty object:

// Basic setup (no spying needed)
const res = { locals: {} };

// If you need to spy on changes to res.locals
const res = { locals: {} };
sinon.spy(res.locals, '__set__'); // Tracks property assignments

2. authMiddleware.login Might Not Be Exported/Imported Correctly

Another common culprit is that the login function isn't being exported properly from your middleware.js file, or you're importing it wrong in your test.

First, double-check your export in middleware.js:

// CommonJS export (most Node.js projects)
module.exports = {
  login: (req, res, next) => { /* your auth logic here */ }
};

// ES Modules export (if using `import/export`)
export const login = (req, res, next) => { /* ... */ };

Then confirm your import in test.js matches:

// CommonJS
const authMiddleware = require('./path/to/middleware');

// ES Modules
import { login } from './path/to/middleware';

If you're importing the module but accessing login incorrectly (e.g., authMiddleware.default.login when using ES Modules), you'll end up trying to call something that isn't a function.

3. Your Middleware Might Expect a next Function

Express middleware typically accepts three parameters: req, res, and next (the function to pass control to the next middleware). If your login middleware uses next() but you're not passing it in your test, this can cause unexpected errors or broken logic.

Update your test to include a mock next function:

it('it must check that function creates the token', () => { 
  const req = { body: { email: 'user@mail.com', password: '12345' } };
  const res = { locals: {} };
  const next = sinon.spy(); // Track if next is called, or use `() => {}` if not needed

  return authMiddleware.login(req, res, next)
    .then(() => { 
      expect(res.locals.token).to.not.be.undefined;
      // Add this if your middleware calls next() on success:
      // expect(next.called).to.be.true;
    })
    .catch(err => console.log(err)); 
});

4. Ensure login Returns a Promise (If Using .then())

Your test uses .then() on the result of authMiddleware.login, which assumes the function returns a Promise. If your middleware uses callback-based logic instead, you'll get an error because you can't call .then() on undefined or a non-Promise value.

If your middleware uses callbacks, adjust the test to use done():

it('it must check that function creates the token', (done) => { 
  const req = { body: { email: 'user@mail.com', password: '12345' } };
  const res = { locals: {} };
  const next = (err) => {
    if (err) return done(err); // Pass errors to Mocha
    expect(res.locals.token).to.not.be.undefined;
    done(); // Signal test completion
  };

  authMiddleware.login(req, res, next);
});

Or, refactor your middleware to return a Promise for cleaner test code:

// In middleware.js
exports.login = (req, res) => {
  return new Promise((resolve, reject) => {
    // Your authentication logic here
    if (/* credentials are valid */) {
      res.locals.token = generateToken();
      resolve(res);
    } else {
      reject(new Error('Invalid credentials'));
    }
  });
};

内容的提问来源于stack exchange,提问作者Sergei R

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 12:13:07