oguimbal / pg-mem

An in memory postgres DB instance for your unit tests
MIT License
1.98k stars 97 forks source link

Kysely adapter misssing in Wiki #379

Closed MaciejWiatr closed 2 months ago

MaciejWiatr commented 8 months ago

Hi! The kysely adapter is mentioned in Readme, there is an example available in the codebase but it's missing in the Wiki. It'd be lovely to have it there as readme forwards to it to See more details about adapters :)

boehs commented 4 months ago

I'm working on Kysely. I'm using it like

mock.module("../../lib/db", () => {
  return { db: newDb().adapters.createKysely() };
});

unfortunately my migrations script fails because of the !~ operator kysely's migration provider uses.

boehs commented 4 months ago

Now I do this:

mock.module("../../lib/db", () => {
  let mem = newDb();
  mem.public.registerOperator({
    operator: "!~",
    left: DataType.text,
    right: DataType.text,
    returns: DataType.bool,
    implementation: ([lhs, rhs]) => {
      return !new RegExp(rhs).test(lhs);
    },
  });
  return { db: mem.adapters.createKysely() };
});

but I still get "column "c.relnamespace" does not exist". Progress!

MikeJerred commented 4 months ago

Looks like pg-mem does not yet create catalog info e.g. https://github.com/oguimbal/pg-mem/blob/master/src/schema/pg-catalog/pg-class.ts

boehs commented 4 months ago

Would it be possible to mock this info? I'm having unrelated HUGE issues inside bun's testing framework so I can't even play with this for now, but eventually...

JakeTrevor commented 2 months ago

I have a workaround, but its a little sketchy...

The actual migrations themselves (the up functions) tend to work fine on pg-mem; the stuff added by the migrator to make sure the migrations behave well in production is usually the problem. But, we aren't in production! So instead, you can just call each up function on the mocked database yourself.

For me it looks something like this:

import { up as m1 } from "../../migrations/24-08-03-1-auth";
import { up as m2 } from "../../migrations/24-08-03-2-application";

const migrations = [m1, m2];

// ... other setup here
const db = new Kysely() // mocked kysely instance

migrations.forEach((m) => m(db));

Obviously, this won't work for every use case, but for some simple testing/mocking it might be good enough.

oguimbal commented 2 months ago

Hi there, I added some (minimal) info in the Wiki.

I'd need more info when it comes to failing issues :)

Another tip: If a specific query is failing, you can mock it using:

db.public.interceptQueries(sql => {
  if (sql.includes('some well identified sql')) {
     return [{col1: 'abc'}] // manually return the data that the query should return !
  }
  return undefined; // do not mock other queries
});

I'm closing this, open another issue with more info if need be !