Mocking express-rate-limit for unit testing
This question is 4 months old and hasn't received a response so I'll do my best to explain it now that I've worked through and got it working.
So say you are using express-rate-limit like so:
middleware.js
const rateLimit = require('express-rate-limit')
const limiter = rateLimit({
windowMs: 60 * 60 * 1000 * 24, // 24 hour window
max: 5, // start blocking after 5 requests
message:
'Too many requests sent from this IP, please try again after an hour'
})
module.exports = {
limiter
}
app.js
const middleware = require('./middleware')
router.post('/my-rate-limited-api', middleware.limiter, async (req, res) => {
try {
const info = await doSomething('my args', req.body)
res.json(info)
} catch (err) {
res.status(err.status || 400).send(`error: ${err.message}`)
}
})
To be able to test the things inside of this route, you'll need to stub limiter.
In your test file, make sure to include an IP in the req. And in your response, stub
req = {
method: 'POST',
ip: '12.12.123.123',
url: '/my-rate-limited-api',
body: [{ id: '123' }]
}
and
res.headers = {}
and
res.setHeader = (x, y) => { res.headers[x] = y }
beforeEach(function () {
const middleware = require('./middleware')
this.sinon.stub(middleware, 'limiter').callsFake(function (req, res, next) {
return next()
})
res = new Promise(function (resolve, reject) {
doneResolve = this.resolve = resolve
doneReject = this.reject = reject
})
res.headers = {}
res.setHeader = (x, y) => { res.headers[x] = y }
req = {
method: 'POST',
ip: '12.12.123.123',
url: '/my-rate-limited-api',
body: [{ id: '123' }]
}
next = this.sinon.spy(function createDeferredNext () {
let resolve
const promise = new Promise(function () {
resolve = arguments[0]
})
const fn = (arg) => resolve(arg)
fn.then = promise.then.bind(promise)
return fn
})
})
From there, you'll be able to test your function however you like.
it('can test without rate limits', function () {
router(req, res, next)
return res
.then(ret => {
expect(res.statusCode).to.eql(200)
})
})