【问题标题】:How do you test NodeJS to see if a middleware was used?您如何测试 NodeJS 以查看是否使用了中间件?
【发布时间】:2020-10-24 02:23:46
【问题描述】:

如果这是你不应该做的事情,请原谅我,但我已经环顾四周,看看有什么可能。

我想验证我的express 应用是否有一个为该应用调用/使用的中间件。

import express from 'express';
import cors from 'cors';

const app = express();

app.use(cors()); // <----- I WANT TO TEST THIS

app.get('/', (_req, res) => res.send({ hello: 'world' });

app.listen(5000, () => console.log(`Listening on port 5000`));

export default app;

潜力jest测试

import app from './index.ts';

// This is a poor attempt to try and get this to work
test('test if CORS is implemented', () => {
   const mockCors = jest.mock('cors');

   const myApp = app;

   expect(mockCors).toHaveBeenCalledTimes(1);
});

如果有人有解决方案,如果我不应该这样做,背后的原因是什么?

【问题讨论】:

    标签: javascript node.js unit-testing express jestjs


    【解决方案1】:

    我的猜测是您实际上并不关心 cors 是否被调用。您的客户不会对您说“我希望调用 cors 中间件”。客户应该关心的是所提供的服务,而不是它的实现方式。你的测试应该做同样的事情。如果您决定有一天为 CORS 使用另一个模块,那么您的测试应该不需要更改,为什么要更改?

    我(个人)首选的方法就是这样。测试给定一些输入,我的程序给了我想要的输出。只要行为不改变,程序内的一切都可以改变。这会让你在重构时高枕无忧。

    此外,为了测试 Express 应用,您不需要服务器,只需要应用即可。实际上,启动服务器会增加测试的复杂性,因为如果您忘记在它们之后关闭服务器,它们可能会挂起。

    所以在这个例子中,我要做的第一件事就是将你在index.ts 中的所有内容移动到一个名为app.ts 的文件中,然后删除这一行:

    app.listen(5000, () => console.log(`Listening on port 5000`));
    

    而在index.ts,只有这个:

    import app from './app.ts';
    // Start the server
    app.listen(5000, () => console.log(`Listening on port 5000`));
    

    然后,我将使用 Supertest 和 Jest 来向该应用发出请求:

    npm i -D supertest
    

    然后,在您的测试文件中,测试对客户重要的内容:

    import request from 'supertest';
    import app from './app.js'; // Just import the app, not the server
    
    describe("myApp", () => {
      it('should implement CORS', async() => {
        const { headers } = await request(app).get('/');
        expect(headers['access-control-allow-origin']).toEqual('*');
      });
    });
    

    【讨论】:

    • 我喜欢文件夹结构,但我确实想检查是否调用了cors。我背后的想法,并不是说它只是cors,而是看看开发人员是否在他们应该实现中间件时意外禁用或注释掉了中间件。这是有效的还是出于特定原因这不是一个好主意?
    • 我认为这取决于中间件。对于 CORS,由于提供的功能就在请求响应中,我认为测试该响应是一种更好的方法。但是,如果您有另一个中间件,例如,将请求记录到外部数据库,那么是的,模拟它更有意义
    • 你能举个例子吗?如果你这样做了,将非常感激。此外,您是否发现使用Postmansupertest 之类的内容存在冗余?
    • 虽然this 可能是一个值得探索的方向,但我现在还没有想到的解决方案。这里棘手的部分是cors() 在您导入模块后立即被调用。所以你可能需要在你做import...之前模拟它。至于 Supertest 和 Postman,是的,那将是多余的(要维护 2 个测试代码库不会很愉快?)
    猜你喜欢
    • 2011-08-14
    • 2023-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-16
    • 2021-11-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多