7elephant
7elephant

Reputation: 2929

node.js: Mock http request and response

Is there convenient way to mock the HTTP Request and Response objects for unit testing middlewares?

Upvotes: 45

Views: 59583

Answers (9)

Nagev
Nagev

Reputation: 13207

I do not recommend this solution for real world usage, but this is the hack I used just to avoid exceptions in an experiment.

const mock_response_obj = {
    statusCode: null,
    setHeader: () => {},
    writeHead: () => {},
    end: () => {},
}

Obviously extend it as needed. Sharing in case anyone else is looking for a simple stopgap.

Upvotes: 0

Taku
Taku

Reputation: 5928

Belatedly, if you're looking only to unit test the handler, you could inject express.Request and express.Response objects into the request function, or in this case, your middleware. One that seemed to provide the minimal methods while keeping it simple was, for me, @jest-mock/express

If you're using supertest or nock, you're doing an integration test which can couple multiple tests. I'd also look into how it works internally because it is going be a pain to debug once it stops working.

it('should call next',
        async () => {
            const req = getMockReq({
              headers: {
                'user-agent': 'Chrome',
              },
              path: '/path',
            })
            const{res, next, clearMockRes} = getMockRes({})
            await middleware(req, res, next)

            expect(res.send).not.toHaveBeenCalledWith()
            expect(next).toHaveBeenCalled()
        })

Upvotes: 2

Scalalang2
Scalalang2

Reputation: 546

I encourage you to use motty. why do we need an another code?

Upvotes: -1

Ed_
Ed_

Reputation: 19098

Mockery looks great for this.

Essentially it hijacks require calls, and returns a different object/function stub that you specify.

Upvotes: 1

timsavery
timsavery

Reputation: 183

Check out https://github.com/timsavery/node-hmock or npm install hmock...any feedback welcome! The solution has worked well for me thus far.

Upvotes: 1

Rich Apodaca
Rich Apodaca

Reputation: 29004

From the tag, it looks like this question is about Express. In that case, supertest is very good:

var request = require('supertest')
  , express = require('express');

var app = express();

app.get('/user', function(req, res){
  res.send(201, { name: 'tobi' });
});

request(app)
  .get('/user')
  .expect('Content-Type', /json/)
  .expect('Content-Length', '20')
  .expect(201)
  .end(function(err, res){
    if (err) throw err;
  });

For general Node use, Flatiron Nock looks like a good option:

var nock = require('nock');
var example = nock('http://example.com')
                .get('/foo')
                .reply(200, { foo: 'bar' });

var http = require('http');
var options = {
  host: 'example.com',
  port: 80,
  path: '/foo',
  method: 'GET'
}
var req = http.request(options, function(res) {
  res.on('data', function(chunk) {
    console.log('BODY: ' + chunk);
  });
});

req.on('error', function(e) {
  console.log('error: ' + e);
});

req.end();

Output:

BODY: {"foo":"bar"}

Upvotes: 11

mjs
mjs

Reputation: 65303

It looks like both https://github.com/howardabrams/node-mocks-http and https://github.com/vojtajina/node-mocks can be used to create mock http.ServerRequest and http.ServerResponse objects.

Upvotes: 28

ctide
ctide

Reputation: 5257

I wrote a library to mock out the responses of requests made via standard HTTP or via the request model:

https://github.com/ctide/fakeweb

Upvotes: 2

Tereska
Tereska

Reputation: 771

i'm using nodejutsu mock:

https://github.com/nodejitsu/mock-request

Maybe this is what you are looking for.

Upvotes: 2

Related Questions