46

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

3
  • Is there a reason you don't include real HTTP requests in your test case? Should be reallx feasible in an async test setup. Commented Nov 5, 2011 at 17:39
  • 12
    I went with that, but to be honest it does not feel like a unit test, it's more like integration one. Anyway, so far that is my best option. Commented Nov 5, 2011 at 17:41
  • 9
    I don't want to include real http requests because it makes my tests slower, and less reliable. For example, if one of the services I call is DB backed, and it fails because the DB in QA has been wiped out (or sync'ed with prod, or whatever) then my tests start failing. Also if you don't mock it's near impossible to reliably force certain error cases to happen. No, I like mocks--they make testing easier and more reliable. Commented Jun 3, 2013 at 22:11

9 Answers 9

28

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.

Sign up to request clarification or add additional context in comments.

2 Comments

node-mocks-http looks like a great solution to the original post.
Ok, having just come across this, node-mocks-http is amazing. (As far as testing request handlers without actually making http requests)
11

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"}

1 Comment

This is a old post. But I have one question. supertest, which has request(app), seems to start a server (github.com/tj/supertest/blob/master/index.js#L20), and it is not mocking http reqeusts. Is that true?
2

i'm using nodejutsu mock:

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

Maybe this is what you are looking for.

1 Comment

The project is deprecated. The recommendation is to use "nock" github.com/flatiron/nock
2

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

Comments

2

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

Comments

1

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

Comments

1

Mockery looks great for this.

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

Comments

0

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.

Comments

-1

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.