Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/davesag/mock-req-res
Extensible mock req / res objects for use in unit tests of Express controller and middleware functions.
https://github.com/davesag/mock-req-res
expressjs mock req-res request response testing
Last synced: 10 days ago
JSON representation
Extensible mock req / res objects for use in unit tests of Express controller and middleware functions.
- Host: GitHub
- URL: https://github.com/davesag/mock-req-res
- Owner: davesag
- License: mit
- Created: 2018-08-11T04:19:55.000Z (over 6 years ago)
- Default Branch: develop
- Last Pushed: 2024-04-23T05:52:22.000Z (8 months ago)
- Last Synced: 2024-05-02T00:12:23.859Z (7 months ago)
- Topics: expressjs, mock, req-res, request, response, testing
- Language: JavaScript
- Homepage:
- Size: 2.61 MB
- Stars: 43
- Watchers: 3
- Forks: 6
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- Funding: .github/FUNDING.yml
- License: LICENSE
- Security: SECURITY.md
Awesome Lists containing this project
README
# mock-req-res
Extensible mock `req` / `res` objects for use in unit tests of [`ExpressJS`](https://expressjs.com) controller and middleware functions.
[![NPM](https://nodei.co/npm/mock-req-res.png)](https://nodei.co/npm/mock-req-res/)
## Prerequisites
This library assumes:
1. You are using NodeJS 8+
2. You write properly isolated unit tests of route controllers and ExpressJS middleware functions
3. You use [`sinon`](https://sinonjs.org) version 5 or better.## Install
Add `mock-req-res` as a `devDependency`:
```sh
npm i -D mock-req-res
```If you are using TypeScript you can add [`@types/mock-req-res`](https://www.npmjs.com/package/@types/mock-req-res):
```sh
npm i -D @types/mock-req-res
```## Mocking `req`
To test a controller or middleware function you need to mock a request object.
Do this with:
```js
const req = mockRequest(options)
```The `options` can be anything you wish to attach or override in the request.
The vanilla `mockRequest` gives you the following properties, as well as functions in the form of [`sinon`](https://sinonjs.org) stubs.
```js
app: {},
baseUrl: '',
body: {},
cookies: {},
fresh: true,
headers: {},
hostname: '',
ip: '127.0.0.1',
ips: [],
method: 'GET',
originalUrl: '',
params: {},
path: '',
protocol: 'https',
query: {},
route: {},
secure: true,
signedCookies: {},
stale: false,
subdomains: [],
xhr: true,
accepts: stub(),
acceptsCharsets: stub(),
acceptsEncodings: stub(),
acceptsLanguages: stub(),
get: stub(),
is: stub(),
range: stub(),
```## Mocking `res`
To test a route controller or middleware function you also need to mock a response object.
Do this with:
```js
const res = mockResponse(options)
```The `options` can be anything you wish to attach or override in the request.
The vanilla `mockResponse` gives you the following functions, in the form of [`sinon`](https://sinonjs.org) spies and stubs.
```js
app: {},
headersSent: false,
locals: {},
append: spy(),
attachment: spy(),
clearCookie: spy(),
download: spy(),
end: spy(),
format: spy(),
json: spy(),
jsonp: spy(),
links: spy(),
location: spy(),
redirect: spy(),
render: spy(),
send: spy(),
sendFile: spy(),
sendStatus: spy(),
set: spy(),
setHeader: spy(),
type: spy(),
get: stub(),
getHeader: stub(),
cookie: stub().returns(res), // returns itself, allowing chaining
status: stub().returns(res), // returns itself, allowing chaining
vary: stub().returns(res) // returns itself, allowing chaining
```**Note** you can always add other spies or stubs as needed via the `options`.
## Example
Let's say you have a route controller like this:
```js
const save = require('../../utils/saveThing') // assume this exists.const createThing = async (req, res) => {
const { name, description } = req.body
if (!name || !description) throw new Error('Invalid Properties')
const saved = await save({ name, description })
res.json(saved)
}
```To unit test this you could use [`Mocha`](https://mochajs.org), [`Chai`](http://www.chaijs.com), [`Sinon`](https://sinonjs.org), and [`Proxyquire`](https://github.com/thlorenz/proxyquire) as follows:
```js
const { expect } = require('chai')
const { stub, match } = require('sinon')
const { mockRequest, mockResponse } = require('mock-req-res')
const proxyquire = require('proxyquire')describe('src/api/things/createThing', () => {
const mockSave = stub()const createThing = proxyquire('../../src/api/things/createThing', {
'../../utils/saveThing': mockSave
})const res = mockResponse()
const resetStubs = () => {
mockSave.resetHistory()
res.json.resetHistory()
}context('happy path', () => {
const name = 'some name'
const description = 'some description'const req = mockRequest({ body: { name, description } })
const expected = { name, description, id: 1 }
before(async () => {
save.returns(expected)
await createThing(req, res)
})after(resetStubs)
it('called save with the right data', () => {
expect(save).to.have.been.calledWith(match({ name, description }))
})it('called res.json with the right data', () => {
expect(res.json).to.have.been.calledWith(match(expected))
})
})// and also test the various unhappy path scenarios.
})
```## See also
- [The Express Request object](https://expressjs.com/en/api.html#req) — `req`
- [The Express Response object](https://expressjs.com/en/api.html#res) - `res`## Development
### Branches
| Branch | Status | Coverage | Audit | Notes |
| ------ | ------ | -------- | ----- | ----- |
| `develop` | [![CircleCI](https://circleci.com/gh/davesag/mock-req-res/tree/develop.svg?style=svg)](https://circleci.com/gh/davesag/mock-req-res/tree/develop) | [![codecov](https://codecov.io/gh/davesag/mock-req-res/branch/develop/graph/badge.svg)](https://codecov.io/gh/davesag/mock-req-res) | [![Vulnerabilities](https://snyk.io/test/github/davesag/mock-req-res/develop/badge.svg)](https://snyk.io/test/github/davesag/mock-req-res/develop) | Work in progress |
| `main` | [![CircleCI](https://circleci.com/gh/davesag/mock-req-res/tree/main.svg?style=svg)](https://circleci.com/gh/davesag/mock-req-res/tree/main) | [![codecov](https://codecov.io/gh/davesag/mock-req-res/branch/main/graph/badge.svg)](https://codecov.io/gh/davesag/mock-req-res) | [![Vulnerabilities](https://snyk.io/test/github/davesag/mock-req-res/main/badge.svg)](https://snyk.io/test/github/davesag/mock-req-res/main) | Latest stable release |### Development Prerequisites
- [NodeJS](https://nodejs.org). I use [`nvm`](https://github.com/creationix/nvm) to manage Node versions — `brew install nvm`.
### Test it
- `npm test` — runs the unit tests.
- `npm run test:unit:cov` — runs the unit tests with code coverage### Lint it
```sh
npm run lint
```## Contributing
Please see the [contributing notes](CONTRIBUTING.md).