{"id":22221126,"url":"https://github.com/davesag/mock-req-res","last_synced_at":"2025-05-07T21:41:23.870Z","repository":{"id":32854929,"uuid":"144354856","full_name":"davesag/mock-req-res","owner":"davesag","description":"Extensible mock req / res objects for use in unit tests of Express controller and middleware functions.","archived":false,"fork":false,"pushed_at":"2025-01-08T20:42:10.000Z","size":2823,"stargazers_count":43,"open_issues_count":1,"forks_count":6,"subscribers_count":2,"default_branch":"develop","last_synced_at":"2025-05-05T10:44:00.259Z","etag":null,"topics":["expressjs","mock","req-res","request","response","testing"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/davesag.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["davesag"]}},"created_at":"2018-08-11T04:19:55.000Z","updated_at":"2025-01-08T20:42:13.000Z","dependencies_parsed_at":"2023-09-26T07:41:38.530Z","dependency_job_id":"7f86348f-c39b-4edb-a7f4-bc75fb28e90d","html_url":"https://github.com/davesag/mock-req-res","commit_stats":{"total_commits":347,"total_committers":9,"mean_commits":38.55555555555556,"dds":"0.12391930835734866","last_synced_commit":"4230b5c188bd01e07c71ccee03a4d5bb2581aed0"},"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davesag%2Fmock-req-res","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davesag%2Fmock-req-res/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davesag%2Fmock-req-res/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davesag%2Fmock-req-res/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/davesag","download_url":"https://codeload.github.com/davesag/mock-req-res/tar.gz/refs/heads/develop","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252961488,"owners_count":21832185,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["expressjs","mock","req-res","request","response","testing"],"created_at":"2024-12-02T23:12:21.508Z","updated_at":"2025-05-07T21:41:23.849Z","avatar_url":"https://github.com/davesag.png","language":"JavaScript","funding_links":["https://github.com/sponsors/davesag"],"categories":["JavaScript"],"sub_categories":[],"readme":"# mock-req-res\n\nExtensible mock `req` / `res` objects for use in unit tests of [`ExpressJS`](https://expressjs.com) controller and middleware functions.\n\n[![NPM](https://nodei.co/npm/mock-req-res.png)](https://nodei.co/npm/mock-req-res/)\n\n## Prerequisites\n\nThis library assumes:\n\n1. You are using NodeJS 8+\n2. You write properly isolated unit tests of route controllers and ExpressJS middleware functions\n3. You use [`sinon`](https://sinonjs.org) version 5 or better.\n\n## Install\n\nAdd `mock-req-res` as a `devDependency`:\n\n```sh\nnpm i -D mock-req-res\n```\n\nIf you are using TypeScript you can add [`@types/mock-req-res`](https://www.npmjs.com/package/@types/mock-req-res):\n\n```sh\nnpm i -D @types/mock-req-res\n```\n\n## Mocking `req`\n\nTo test a controller or middleware function you need to mock a request object.\n\nDo this with:\n\n```js\nconst req = mockRequest(options)\n```\n\nThe `options` can be anything you wish to attach or override in the request.\n\nThe vanilla `mockRequest` gives you the following properties, as well as functions in the form of [`sinon`](https://sinonjs.org) stubs.\n\n```js\napp: {},\nbaseUrl: '',\nbody: {},\ncookies: {},\nfresh: true,\nheaders: {},\nhostname: '',\nip: '127.0.0.1',\nips: [],\nmethod: 'GET',\noriginalUrl: '',\nparams: {},\npath: '',\nprotocol: 'https',\nquery: {},\nroute: {},\nsecure: true,\nsignedCookies: {},\nstale: false,\nsubdomains: [],\nxhr: true,\naccepts: stub(),\nacceptsCharsets: stub(),\nacceptsEncodings: stub(),\nacceptsLanguages: stub(),\nget: stub(),\nis: stub(),\nrange: stub(),\n```\n\n## Mocking `res`\n\nTo test a route controller or middleware function you also need to mock a response object.\n\nDo this with:\n\n```js\nconst res = mockResponse(options)\n```\n\nThe `options` can be anything you wish to attach or override in the request.\n\nThe vanilla `mockResponse` gives you the following functions, in the form of [`sinon`](https://sinonjs.org) spies and stubs.\n\n```js\napp: {},\nheadersSent: false,\nlocals: {},\nappend: spy(),\nattachment: spy(),\nclearCookie: spy(),\ndownload: spy(),\nend: spy(),\nformat: spy(),\njson: spy(),\njsonp: spy(),\nlinks: spy(),\nlocation: spy(),\nredirect: spy(),\nrender: spy(),\nsend: spy(),\nsendFile: spy(),\nsendStatus: spy(),\nset: spy(),\nsetHeader: spy(),\ntype: spy(),\nget: stub(),\ngetHeader: stub(),\ncookie: stub().returns(res), // returns itself, allowing chaining\nstatus: stub().returns(res), // returns itself, allowing chaining\nvary: stub().returns(res) // returns itself, allowing chaining\n```\n\n**Note** you can always add other spies or stubs as needed via the `options`.\n\n## Example\n\nLet's say you have a route controller like this:\n\n```js\nconst save = require('../../utils/saveThing') // assume this exists.\n\nconst createThing = async (req, res) =\u003e {\n  const { name, description } = req.body\n  if (!name || !description) throw new Error('Invalid Properties')\n  const saved = await save({ name, description })\n  res.json(saved)\n}\n```\n\nTo 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:\n\n```js\nconst { expect } = require('chai')\nconst { stub, match } = require('sinon')\nconst { mockRequest, mockResponse } = require('mock-req-res')\nconst proxyquire = require('proxyquire')\n\ndescribe('src/api/things/createThing', () =\u003e {\n  const mockSave = stub()\n\n  const createThing = proxyquire('../../src/api/things/createThing', {\n    '../../utils/saveThing': mockSave\n  })\n\n  const res = mockResponse()\n\n  const resetStubs = () =\u003e {\n    mockSave.resetHistory()\n    res.json.resetHistory()\n  }\n\n  context('happy path', () =\u003e {\n    const name = 'some name'\n    const description = 'some description'\n\n    const req = mockRequest({ body: { name, description } })\n    const expected = { name, description, id: 1 }\n    before(async () =\u003e {\n      save.returns(expected)\n      await createThing(req, res)\n    })\n\n    after(resetStubs)\n\n    it('called save with the right data', () =\u003e {\n      expect(save).to.have.been.calledWith(match({ name, description }))\n    })\n\n    it('called res.json with the right data', () =\u003e {\n      expect(res.json).to.have.been.calledWith(match(expected))\n    })\n  })\n\n  // and also test the various unhappy path scenarios.\n})\n```\n\n## See also\n\n- [The Express Request object](https://expressjs.com/en/api.html#req) — `req`\n- [The Express Response object](https://expressjs.com/en/api.html#res) - `res`\n\n## Development\n\n### Branches\n\n\u003c!-- prettier-ignore --\u003e\n| Branch | Status | Coverage | Audit | Notes |\n| ------ | ------ | -------- | ----- | ----- |\n| `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 |\n| `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 |\n\n### Development Prerequisites\n\n- [NodeJS](https://nodejs.org). I use [`nvm`](https://github.com/creationix/nvm) to manage Node versions — `brew install nvm`.\n\n### Test it\n\n- `npm test` — runs the unit tests.\n- `npm run test:unit:cov` — runs the unit tests with code coverage\n\n### Lint it\n\n```sh\nnpm run lint\n```\n\n## Contributing\n\nPlease see the [contributing notes](CONTRIBUTING.md).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdavesag%2Fmock-req-res","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdavesag%2Fmock-req-res","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdavesag%2Fmock-req-res/lists"}