jwolsborn
jwolsborn

Reputation: 716

Stubbing pg-promise using Sinon

I'm trying to test the following functions that make queries on a postgres database using pg-promise. I won't to be able to stub the pg-promise function db.one so that it returns a value I defined so I can write tests that show that upon returning some data it sends back said data and when db.one encounters an error it sends back that error message.

Below is an example function

queries.js

const pgp = require('pg-promise')({noLocking:true});

const config = {
...
};

const db = pgp(config);

function getFaculty(req, res, next) {

    db.one('SELECT * FROM users WHERE first_name= $1', [req.query.firstName])
        .then((data)=> {
            let user = {
                firstName: data.first_name,
                lastName: data.last_name,
                phoneNum: data.phone_number
            }
            return res.status(200).send(user)
        })
        .catch((err)=>{
            console.log(err.message);
            return next(err)
        })
}

Here is an example test

queries.test.js

const db = require('../routes/queries');
const assert = require('assert');
let sinon = require('sinon')

let pgp = sinon.stub().returns({
    one: sinon.stub().returns({
        firstName: "Josh",
        lastName: "Stevens",
        phoneNum: "1234567"
    }),
    any: sinon.stub(),
    none: sinon.stub()
})


describe('test queries', ()=>{
    it('Succesfully test getFaculty query', ()=>{

        let req = {
            query: {
                firstName: 'Josh'
            }
        };

        let expectedRes = {
            firstName: "Josh",
            lastName: "Stevens",
            phoneNum: "1234567"
        }

       let res = db.getFaculty(req)
        assert(res, expectedRes)

    })
})

I don't believe I'm properly stubbing out pg-promise as I get an unresolved return.

Upvotes: 1

Views: 531

Answers (1)

Lin Du
Lin Du

Reputation: 102277

Here is the unit test solution:

queries.js:

const pgp = require("pg-promise")({ noLocking: true });

const config = {};

const db = pgp(config);

function getFaculty(req, res, next) {
  return db
    .one("SELECT * FROM users WHERE first_name= $1", [req.query.firstName])
    .then((data) => {
      let user = {
        firstName: data.first_name,
        lastName: data.last_name,
        phoneNum: data.phone_number,
      };
      return res.status(200).send(user);
    })
    .catch((err) => {
      console.log(err.message);
      return next(err);
    });
}

exports.getFaculty = getFaculty;
exports.db = db;

queries.test.js:

const { getFaculty, db } = require("./queries");
const sinon = require("sinon");

describe("queries", () => {
  afterEach(() => {
    sinon.restore();
  });
  it("should get faculty", async () => {
    const mReq = { query: { firstName: "Lin" } };
    const mRes = { status: sinon.stub().returnsThis(), send: sinon.stub() };
    const mNext = sinon.stub();
    const mData = { first_name: "Lin", last_name: "Du", phone_number: 123 };
    const oneStub = sinon.stub(db, "one").resolves(mData);

    await getFaculty(mReq, mRes, mNext);
    sinon.assert.calledWith(mRes.status, 200);
    sinon.assert.calledWith(mRes.send, { firstName: "Lin", lastName: "Du", phoneNum: 123 });
    sinon.assert.calledWith(oneStub, "SELECT * FROM users WHERE first_name= $1", ["Lin"]);
  });

  it("should call error handler middleware", async () => {
    const mReq = { query: { firstName: "Lin" } };
    const mRes = { status: sinon.stub().returnsThis(), send: sinon.stub() };
    const mNext = sinon.stub();
    const mError = new Error("connect error");
    const oneStub = sinon.stub(db, "one").rejects(mError);

    await getFaculty(mReq, mRes, mNext);
    sinon.assert.calledWith(mNext, mError);
    sinon.assert.calledWith(oneStub, "SELECT * FROM users WHERE first_name= $1", ["Lin"]);
  });
});

Unit test result with 100% coverage:

 queries
    ✓ should get faculty
connect error
    ✓ should call error handler middleware


  2 passing (11ms)

-----------------|----------|----------|----------|----------|-------------------|
File             |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
-----------------|----------|----------|----------|----------|-------------------|
All files        |      100 |      100 |      100 |      100 |                   |
 queries.js      |      100 |      100 |      100 |      100 |                   |
 queries.test.js |      100 |      100 |      100 |      100 |                   |
-----------------|----------|----------|----------|----------|-------------------|

Source code: https://github.com/mrdulin/mocha-chai-sinon-codelab/tree/master/src/stackoverflow/59062660

UPDATE:

From pg-promise author:

Version 11 of pg-promise removed all locking functionality, including option noLocking.

Upvotes: 3

Related Questions