elysiajs / elysia

Ergonomic Framework for Humans
https://elysiajs.com
MIT License
10.25k stars 219 forks source link

Can not close/stop/shutdown the server in e2e tests. #276

Closed ivankupach closed 11 months ago

ivankupach commented 12 months ago

Here my test.ts file:

import { describe, expect, it } from 'bun:test';
import { app } from './server';

describe('Auth module test', () => {
  it('Register user', async () => {
    const response = await app
      .handle(
        new Request(authUrl + AUTH_EMAIL_REGISTRATION, {
          method: 'POST',
          body: JSON.stringify(body),
          headers: {
            'content-type': 'application/json',
          },
        }),
      )
      .then((res) => res.json());
    expect(response.user.email).toBe(body.user.email);
    await app.stop();
  });
});

My test is passed ✓ Auth module test > Register user [1458.94ms]

but server is continue working and the test does not ending

ivankupach commented 11 months ago

The issue was in DB, for testing we need to close the pool. In my case its postgres-js.

const queryClient = postgres(...);
make some tests;
await queryClient.end();
gabbrieu commented 11 months ago

@intelligent-person Do you know how to do this with SQLite? My test cases are taking around 300~350ms to complete, while the test itself is taking 5ms (I did just one test to see). And because of that I'm thinking that this could be the problem

ivankupach commented 11 months ago

@gabbrieu this is my app setup

export const app = (db: PostgresJsDatabase) =>
  new Elysia()
    .use(setupApp(db))
    .get('/', ({ set }) => {
      set.redirect = '/swagger';
    })
    .get(GREETING, () => 'Hi!');

const App = app(db).listen(env.SERVER_PORT);

My route test

describe('Auth module test', () => {
  let client: postgres.Sql<{}>;
  let db: PostgresJsDatabase;

  beforeEach(async () => {
    client = postgres(dbCredentialsString);
    db = drizzle(client);
  });

  afterEach(async () => {
    await client.end();
  });

  it('Register a user', async () => {
    const response = await app(db)
      .handle(
        new Request(
          AUTH + AUTH_EMAIL_REGISTRATION,
          {
            method: 'POST',
            body: JSON.stringify(authBody),
            headers: {
              'Content-Type': 'application/json',
            },
          },
        ),
      )
      .then((res: Response) => res.json());
    expect(response.user.email).toBe(authBody.user.email);
  });
});

just pass the db to each module in app.module.ts for example

app
    .use(authPlugin(db))
    .use(eventsPlugin(db))
    .use(usersPlugin(db))

and in plugin pass db to repositories and then add that repo to state and you can use db in controllers and services

gabbrieu commented 11 months ago

Oh thanks, I'll try it later!