Hey, general question regarding integration / E2E ...
# orm-help
d
Hey, general question regarding integration / E2E testing with nestJS & jest: we do the following: globalSetup -> Migrate & seed Database. run test suite against docker-compose DB This works... But we have a case where we need to match a snapshot with our generated Export and need the entry's ids to match. so we would love to do something like this (unrelated to my eg above): (fresh db on a test basis, not globalTestSetup basis)
Copy code
describe("UserService", () => {
  let connection: Connection

  beforeAll(async (done) => {
    connection = await useRefreshDatabase({ connection: 'memory' })
    await useSeeding()

    const user = await factory(User)().make()
    const createdUser = await factory(User)().create()

    await runSeeder(CreateUserSeed)
    done()
  })

  afterAll(async (done) => {
    await tearDownDatabase()
    done()
  })

  test('Should ...', () => { ... })
})
Can anybody chime in
r
Hi @Davedavedave - it's not in code but running
prisma migrate reset
drops the current db, re-creates it and runs the seed data.. It may not be good for running in tests though ..
d
thank you - i found this command in the docs, but how would i execute this in a jest test 🤔 as there is no globalSetup / teadDown variant on a testFile basis
l
That should be run in a CI/CD pipeline like github actions
d
we run it in ci/cd, but nevertheless this doesnt generate stability regarding created Ids, as other tests might create or delete a record as well. As every test shares the same DB and is not tested in isolation
are you suggesting running each e2e test file in separate container on a per file basis to circum vent this? to me this seems pretty cumbersome tbh. My example above is taken from: https://github.com/w3tecch/typeorm-seeding
Are you suggesting something like this @Richard Ward ?
Copy code
// user.controller.spec.ts
import { execSync } from "child_process";
beforeAll(() => {
// drop db, recreate, seed
execSync('prisma migrate reset')
})
l
Your problem is : You are creating some data and now you want to match if the same exact data is created in DB. You are unable to do that now because at the same time other tests are creating data as well in the same db.
👌 1
I think i misunderstood your problem when i wrote the CI/CD as the solution
d
yepp, you understood my problem 🙂
r
@Davedavedave - I'm not sure if that is the best way but it is "a way" .. 😞
The way I do testing is I create the data in the test: something like:
Copy code
it('returns the matching user', async () => {
  const userDetails = createRandomUserObject();
  const createdUser = await prisma.user.create({ data: userDetails });

  const response = await queryApi(USER, { userId: createdUser.id });

  expect(createdUser).toEqual(expect.objectContaining(response.data.user));
});
with the `createRandomUserObject`:
Copy code
export const createRandomUserObject = (partialUser: Partial<Prisma.UserCreateInput> | null = null) => {
  return {
    email: randomString(15) + '@example.com',
    firstname: randomString(15),
    surname: randomString(15),
    ...partialUser,
  };
};
I can now target the user using
createdUser.email
(as that's unique in my circumstances)
d
yeah, this seems fine, but we are migrating a legacy system and need to match the exact output to establish compability! Thank you for taking the time to write your example 🙂
r
aah right - now I understand ..
d
so we compare csv input with csv output from our controller
r
right - then I'm not sure how to do it in code besides the "migrate reset" option ..
d
still the thought lingers that having something along the lines of
Copy code
useRefreshDatabase()
useSeeding()
that prisma exposes for testing would be incredible helpfull
r
I guess, if you have the data in "sql' format then you could do something like:
Copy code
beforeAll(async (done) => {
    await prisma.$executeRaw`${insertDataSQL}`;
    done()
  })

  afterAll(async (done) => {
    await prisma.$executeRaw`${deleteDataSQL}`;

    await prisma.$disconnect()
    done()
  })
d
nope, sadly not. But thank you for taking the time 🙂