Reputation: 2929
Is there convenient way to mock the HTTP Request and Response objects for unit testing middlewares?
Upvotes: 45
Views: 59583
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
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
Reputation: 19098
Mockery looks great for this.
Essentially it hijacks require
calls, and returns a different object/function stub that you specify.
Upvotes: 1
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
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
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
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
Reputation: 771
i'm using nodejutsu mock:
https://github.com/nodejitsu/mock-request
Maybe this is what you are looking for.
Upvotes: 2