Skip to content Skip to sidebar Skip to footer

How To Mock Pg Pool With Sinon

In a previous project I mocked the mysql library with Sinon. I did this like so: X.js: const con = mysql.createPool(config.mysql); ... Some other place in the project: const rows

Solution 1:

Example: I have postgres.js like this.

const { Pool } = require('pg');

const handler = {
  count: async (pgQuery) => {
    try {
      const pool = newPool();
      const res = await pool.query(pgQuery);
      return { count: parseInt(res.rows[0].counter, 10) };
    } catch (error) {
      // Log/Throw error here.
    }
    returnfalse;
  }
}

module.exports = handler;

The spec test I created on postgres.spec.js is like this.

const { expect } = require('chai');
const sinon = require('sinon');
const pgPool = require('pg-pool');
const handler = require('postgres.js');

describe('Postgres', function () {
  it('should have method count that bla bla', asyncfunction () {
    // Create stub pgPool query.const postgreeStubQuery = sinon.stub(pgPool.prototype, 'query');
    postgreeStubQuery.onFirstCall().throws('XXX');
    postgreeStubQuery.onSecondCall().resolves({
      rows: [{ counter: 11 }],
    });

    // Catch case.const catcher = await handler.count('SELECT COUNT()..');
    expect(catcher).to.equal(false);
    expect(postgreeStubQuery.calledOnce).to.equal(true);

    // Correct case.const correct = await handler.count('SELECT COUNT()..');
    expect(correct).to.deep.equal({ count: 11 });
    expect(postgreeStubQuery.calledTwice).to.equal(true);

    // Restore stub.
    postgreeStubQuery.restore();
  });
});

To stub pool.query(), you need to stub pg-pool prototype and method query.

Hope this helps.

Solution 2:

Since you're needing to mock the returned results of a query, I think the easiest solution would be to abstract your database from the the code needing the query results. Example being, your query results are returning information about a person. Create a person.js module with specific methods for interacting with the database.

Your other code needing the person information from the database won't know or care what type of database you use or how you connect to it, all they care to know is what methods are exposed from person.js when they require it.

//person.jsconst { Pool } = require('pg')
// do other database connection things hereconst getPersonById = function (id) {
  // use your query here and return the results
}
module.exports = { getPersonById }

Now in your tests, you mock the person module, not the pg module. Imagine if you had 20 some odd tests that all had the mock MySQL pool set up then you changed to pg, you'd have to change all of those, nightmare. But by abstracting your database connection type/setup, it makes testing much easier, because now you just need to stub/mock your person.js module.

const person = require('../person.js') //or whatever relative file path it's inconst sinon = require('sinon')

describe('person.js', function () {
  it('is stubbed right now', function () {
    const personStub = sinon.stub(person)
    personStub.getPersonById.returns('yup')
  
    expect(personStub.getPersonById()).to.eq('yup')
  })
})

Post a Comment for "How To Mock Pg Pool With Sinon"