【问题标题】:How I can mock an incoming http request in jest using node.js http?我如何使用 node.js http 开玩笑地模拟传入的 http 请求?
【发布时间】:2023-01-21 18:36:44
【问题描述】:

我正在制作一个名为 handle_http.js 的处理程序库:

module.exports.redirectHttpToHttps = (db,req,res)=>{
      const sql = "SELECT * from redirect where use_in_http = 1 and exact_match = 1 and url_from = ? and exact_match=1 LIMIT 1";
     // redirection logic
}

我制作了一个使用该库的 http 服务器:

const http = require('node:http');
// A simple database connection generator
const db = require('./db.js');

const handler = require('./handle_http.js');

http.createServer((req,res){
  handler.redirectHttpToHttps(db,req,res);
});
http.listen(80);

但在运行实际代码之前,我想使用jest (test_redirect.jest.js) 进行一些单元测试:

const db = require('../src/db.js');
const redirect = require('../src/handle_http.js');

test("redirect to https",()=>{
    const dbHandler = db(':memory:');
    database.exec(`
            INSERT INTO redirect (url_from,url_to,method,http_status_code,use_in_http,exact_match) VALUES
            ('http://google.com/mytest','http://yahoo.com','GET',301,1,1),
            ('http://google.com/mytest2','http://yandex.com','GET',302,1,0),
            ('http://google.com?q=ikariam','http://yandex.com','GET',302,1,1),
            ('http://example.com/products','https://fakestoreapi.com/products','POST',308,1,1),
            ('http://example.net/products','https://fakestoreapi.com/products','POST',308,1,0),
            ('http://example.net','https://fakestoreapi.com/products','POST',308,1,0);
        `,function(error){ err_callback(error); });
    
    // need to make fake request so I can call the `redirectHttpToHttps`
    redirect.redirectHttpToHttps(db,/*mocked_request*/,/*some way to assert the response*/)
});

如您所见,我能够使用虚假数据填充内存数据库,但我不知道如何:

  1. 如何伪造传入的 http 请求。
  2. 我如何断言 http 响应具有适当的状态代码和标头

    你能帮我吗?提供的example 不适合我的情况,因为我需要在我自己的用 nodejs 编写的 http 服务器中测试 http 处理逻辑。

【问题讨论】:

    标签: javascript node.js http jestjs


    【解决方案1】:

    一种方法是使用 supertest 并动态创建一个 http 服务器:

    const http = require('node:http');
    const request = require('supertest');
    
    
    const db = require('../src/db.js');
    const redirect = require('../src/handle_http.js');
    
    test("redirect to https",(done)=>{
        const dbHandler = db(':memory:');
        database.exec(`
                INSERT INTO redirect (url_from,url_to,method,http_status_code,use_in_http,exact_match) VALUES
                ('http://google.com/mytest','http://yahoo.com','GET',301,1,1),
                ('http://google.com/mytest2','http://yandex.com','GET',302,1,0),
                ('http://google.com?q=ikariam','http://yandex.com','GET',302,1,1),
                ('http://example.com/products','https://fakestoreapi.com/products','POST',308,1,1),
                ('http://example.net/products','https://fakestoreapi.com/products','POST',308,1,0),
                ('http://example.net','https://fakestoreapi.com/products','POST',308,1,0);
            `,function(error){ done(error); });
        
        const server = http.createServer((req,res)=>{
            redirect.redirectHttpToHttps(dbHandler,req,res)
        });
    
        request(server)
           .get('/mytest')
           .set('Host','google.com')
           .expect(301,done);
    });
    
    

    注意行:

       request(server)
           .get('/mytest')
           .set('Host','google.com')
           .expect(301,done);
    

    使用来自supertestrequest 函数,我提供了一个不监听任何端口的服务器实例:

        const server = http.createServer((req,res)=>{
            redirect.redirectHttpToHttps(dbHandler,req,res)
        });
    

    在测试期间,您可以完全避免 https 并创建调用您要执行的 http 处理函数的纯非 ssl 服务器。


    各种各样的

    此外,您的代码在以下部分有错误:

    database.exec(`
                INSERT INTO redirect (url_from,url_to,method,http_status_code,use_in_http,exact_match) VALUES
                ('http://google.com/mytest','http://yahoo.com','GET',301,1,1),
                ('http://google.com/mytest2','http://yandex.com','GET',302,1,0),
                ('http://google.com?q=ikariam','http://yandex.com','GET',302,1,1),
                ('http://example.com/products','https://fakestoreapi.com/products','POST',308,1,1),
                ('http://example.net/products','https://fakestoreapi.com/products','POST',308,1,0),
                ('http://example.net','https://fakestoreapi.com/products','POST',308,1,0);
            `,function(error){ err_callback(error); });
    

    未定义函数 err_callback。因此,我使用了 documentation 中定义的开玩笑的 done 函数

    所以测试的重构部分是:

        database.exec(`
                INSERT INTO redirect (url_from,url_to,method,http_status_code,use_in_http,exact_match) VALUES
                ('http://google.com/mytest','http://yahoo.com','GET',301,1,1),
                ('http://google.com/mytest2','http://yandex.com','GET',302,1,0),
                ('http://google.com?q=ikariam','http://yandex.com','GET',302,1,1),
                ('http://example.com/products','https://fakestoreapi.com/products','POST',308,1,1),
                ('http://example.net/products','https://fakestoreapi.com/products','POST',308,1,0),
                ('http://example.net','https://fakestoreapi.com/products','POST',308,1,0);
            `,function(error){ done(error); });
    

    【讨论】:

      猜你喜欢
      • 2021-05-27
      • 1970-01-01
      • 1970-01-01
      • 2019-02-28
      • 2020-11-18
      • 1970-01-01
      • 2021-07-02
      • 1970-01-01
      • 2017-07-01
      相关资源
      最近更新 更多