March 3, 2021 · 4 min read

Writing tests with Sequelize, GraphQL and Typescript

How to write tests with Jest, Sequelize and Typescript

At Shepherd, we leverage GraphQL, Apollo, Typescript, and Sequelize extensively in our testing practices. Here's a practical guide for testing these technologies together.

Key Setup Patterns

Initialize Server and Database

beforeAll(async () => {
  [server, sequelize] = await Promise.all([
    testApolloServer(),
    initializeDatabase({ logging: false }),
  ]);
});

Create Test User

beforeEach(async () => {
  user = await User.create({ email: faker.internet.email() });
});

Clean Database After Tests

afterEach(async () => {
  await Promise.all(
    Object.values(sequelize.models).map(async (model) => {
      return model.destroy({ where: {}, truncate: true, cascade: true });
    })
  );
});

Important: Run Jest with --runInBand flag since parallel test execution creates database cleaning conflicts.

Close Database Connection

afterAll(async () => {
  await sequelize.close();
});

Testing Mutations

Here's how to test GraphQL mutations with proper type safety and context injection:

test('should create organization', async () => {
  const companyName = faker.company.companyName();
  const thisServer = await testApolloServer(() => ({
    user,
  }));
  const res = await thisServer.mutate<
    CreateOrganizationMutation,
    CreateOrganizationMutationVariables
  >({
    mutation: CreateOrganizationDocument,
    variables: {
      input: {
        name: companyName,
        type: OrganizationTypeEnumGenerated.Brokerage,
      },
    },
  });

  expect(res?.data).toMatchSnapshot({
    createOrganization: {
      organization: {
        id: expect.any(String),
        name: expect.any(String),
      },
    },
  });
});

Apollo Server Test Configuration

const testApolloServer = async (context = () => ({})) => {
  const schema = await buildSchema({
    resolvers: [UserResolver, OrganizationResolver, RetoolResolver],
    authChecker: customAuthChecker,
    container: Container,
  });

  const server = new ApolloServer({
    schema,
    context,
  });

  return createTestClient(server);
};

This approach allows dynamic context configuration for different test scenarios, enabling flexible authentication state management during testing.

MoCofounder & CTO, Shepherd
Follow on X