提问者:小点点

为什么我的sinon存根表现得像在调用真实函数?


我试图遵循这个例子:https://www.alexjamesbrown.com/blog/development/stubbing-middleware-testing-express-supertest/ 但sinon存根似乎没有执行包装的代码。我已经看到了很多关于这个问题的堆栈溢出帖子,但没有一个答案可以帮助我弄清楚我做错了什么。每当我运行测试时,我都会收到以下错误:

1) should return a list of sites

0 次通过(42 毫秒)1 次失败

    < Li > GET/API/config/build pro/sites应返回站点列表:错误:预期200“正常”,测试时得到403“禁止”。测试时的_ assert status(node _ modules \ supertest \ lib \ Test . js:268:12)。_ assert function(node _ modules \ supertest \ lib \ test . js:283:11)at test . assert(node _ modules \ supertest \ lib \ test . js:173:18)at server . local assert(node _ modules \ supertest \ lib \ test . js:131:12)at emit closent(net . js:1655:8)at processTicksAndRejections(internal/process/task _ queues . js:83:21)

这让我相信它不是在调用存根代码,而是在执行实际的授权函数。这是我的代码:

const express = require('express');
const app = express();
const authorization = require('./security/authorization');

const configRoutes = require('./api/routes/config');

app.all('/api/*', authorization.authorize);
app.use('/api/config', configRoutes);

module.exports = app;
const aad = require('azure-ad-jwt');

module.exports.authorize = (req, res, next) => {
    if(!req.headers.authorization){
        res.status(403).json({
            message: "Auth failed"
        });
        return;
    }

    const jwtToken = req.headers.authorization.replace('Bearer ', '');

    aad.verify(jwtToken, null, function (err, result) {
        if (result) {
            next();
        } else {
            res.status(401).json({
                message: "Auth failed"
            });
        }
    });
};
const request = require('supertest');
const sinon = require('sinon');
const app = require('../app');
const authorization = require('../security/authorization');

var agent;

describe('GET /api/names', () => {
    before(() => {
        ensureAuthenticatedSpy = sinon.stub(authorization, 'authorize');

        ensureAuthenticatedSpy.callsArgWithAsync(2);

        agent = require('supertest')
            .agent(require('../app'));
    });

    it('should return a list of names', done => {
        agent
            .get('/api/config/buildPro/sites')
            .expect(200)
            .end((err, res) => {
                if (err) return done(err);
                done();
            });
    });
});

共1个答案

匿名用户

而是执行实际的授权

这正是正在发生的事情。

在服务器中注意此代码:

app.all('/api/*', authorization.authorize);

这解决了授权函数在这个特定程序状态下的引用,并表示将使用这个特定函数(原始函数!)用于程序的其余部分。

这:

ensureAuthenticatedSpy = sinon.stub(authorization, 'authorize');

后来被调用,鉴于西农无权更改对先前捕获的原始授权的引用……不适用。

IOW,基本Javascript应用程序中的依赖注入并不像人们想要的那么简单。

要解决此问题,您可以在app.js中更改原始路由:

app.all('/api/*', (req, res, next) => authorization.authorize(req, res, next));

现在,您的闭包会在每次调用< code > authorization . authorize 时解析它,启用您感兴趣的模仿/监视功能。然而,这种解决方案并不完美。