简体   繁体   中英

How I can mock an incomming http request in jest using node.js http?

I am making a handler library named 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
}

And I made a http server where consumes the library:

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);

But before running into an actual code, I want to make some unit tests using 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*/)
});

As you can see, I am able to populate an in-memory database with fake data, but I do not know how:

  1. How I can make a fake an incomming http request.
  2. How I can assert that http response has appropriate status code and headers

Can you help me with that? The provided example does not cut in my case because I need to test the http handling logic in my own http server written in nodejs.

An approach is to use the supertest and create an http server on the fly:

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);
});

Pay attention into the lines:

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

Using request function comming from supertest I provide a server instance that does not listen to any port:

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

During testing, you can avoid the https at all and create pure non-ssl servers that call the http handling function you want to perform.


Miscelanous

Also, your code has an error at section:

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); });

Function err_callback is not defined. Therfore I used the jest's done function as defined into documentation

So the refactored part of the test is:

    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); });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM