porsager / postgres

Postgres.js - The Fastest full featured PostgreSQL client for Node.js, Deno, Bun and CloudFlare
The Unlicense
7.55k stars 274 forks source link

Ability to inspect query fragments without database connection #816

Open wms opened 9 months ago

wms commented 9 months ago

Thanks for building this library, it's very impressive and I'm enjoying using it so far.

It would be very helpful if I could unit test some of my query-generating functions without the need for a DB connection. For example, with an .inspect() method or similar that returns a simple {text, values} structure or similar without inducing a DB round-trip.

There appears to be some discussion around this requirement in https://github.com/porsager/postgres/discussions/760 and the current workaround appears to be to catch the exception and then inspect the query and parameters properties on the exception, which may not be ideal.

t-d-d commented 8 months ago

I am using below for mocking with jest. Only a start and only covers part of the api but I have used to unit test some of my code.

import sql from "./db";
jest.mock('./db');
const parseQuery = ([segments, ...params]) => typeof segments === 'string' ? segments : segments.reduce((a, v, i) => `${a}${v}${params[i] ?? ''}`, '')
sql.mockImplementation(s => typeof s === 'string' ? s : [])

it("a test", () => {
  ...
  const query = parseQuery(sql.mock.lastCall)
  const [_, ...values] = sql.mock.lastCall
  ...
}

I also mock sql.begin to capture statements per transaction:

  sql.tx = []
  sql.begin = jest.fn(func => {
    const txMockSql = jest.fn(sql)
    sql.tx.push(txMockSql)
    return func(txMockSql)
  })
  ...
  expect(parseQuery(sql.tx[0].mock.lastCall)).toMatch(/SELECT somesqlintx0/)