mock-req-res
    DefinitelyTyped icon, indicating that this package has TypeScript declarations provided by the separate @types/mock-req-res package

    1.2.1 • Public • Published

    mock-req-res

    Extensible mock req / res objects for use in unit tests of ExpressJS controller and middleware functions.

    NPM

    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 version 5 or better.

    Install

    Add mock-req-res as a devDependency:

    npm i -D mock-req-res

    If you are using TypeScript you can add @types/mock-req-res:

    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:

    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 stubs.

    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:

    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 spies and stubs.

    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:

    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, Chai, Sinon, and Proxyquire as follows:

    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

    Development

    Branches

    Branch Status Coverage Audit Notes
    develop CircleCI codecov Vulnerabilities Work in progress
    main CircleCI codecov Vulnerabilities Latest stable release

    Development Prerequisites

    • NodeJS. I use 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

    npm run lint

    Contributing

    Please see the contributing notes.

    Install

    npm i mock-req-res

    DownloadsWeekly Downloads

    15,319

    Version

    1.2.1

    License

    MIT

    Unpacked Size

    18.4 kB

    Total Files

    7

    Last publish

    Collaborators

    • davesag