Skip to main content

Testing

Testing is the cornerstone of a reliable production quality applicaton. The library provides all the tools you might need to easily test your event publishing and event handlers. We will use MemoryEventBus to test the runtime behavior of our code.

Publishing Events​

Create a sample MemoryEventBus with the schema of events that you publish. You can also import the Publish function from the generated code. See below.

import { MemoryEventBus } from "graphql-eventbus";
import schema from "./bus";
import { Publish } from "./generated/codegen-event-publisher";

const createSamplePublisher = async () => {
const bus = new MemoryEventBus({
schema,
});
await bus.init();
const publish: Publish = async (args) => {
await bus.publish(args);
};
return publish;
};

This function can be imported in your test file to publish events and detect errors during testing.

Consuming Events​

Testing event handlers require a tedious task of generating mock data. Don't worry though: with the power of GraphQL schema, generating mock data is as simple as a function call. All we need to do is add mocks to our consumer schema to create a mocked schema. See an example. You can add your custom mock functions but we are using the default mocks from graphql-scalars library.

With the help of mocked schema, you can easily generate mock data for each event using Validator class exported from the library. It exposes a sample method which takes the event name and an optional override object to override fields in the final payload.

import { mocks } from "graphql-scalars";
import { addMocksToSchema, MockStore } from "@graphql-tools/mock";

const store = new MockStore({
schema: consumerSchema,
mocks: mocks,
});

export const eventSchemaWithMocks = addMocksToSchema({
schema: consumerSchema,
preserveResolvers: true,
store,
});

const validator = new Validator(eventSchemaWithMocks);

export const sampleEventData: EventSampler = (args: any) => {
store.reset();
const data = validator.sample(args.event);
if (data.errors || !data.data) {
console.log(data.errors);
throw new Error("Encountered error when generating data");
}
// eslint-disable-next-line @typescript-eslint/ban-types
return { ...data.data[args.event], ...args.override };
};

To make our sampler function easy to use in typescript, we also generate code for EventSampler using eventSampler: true option in graphql-eventbus-config plugin.

function eventSampler(args: {
event: "EmailOpenEvent";
override?: Partial<EmailOpenEvent>;
}): EmailOpenEvent;
function eventSampler(args: {
event: "UserDeletedEvent";
override?: Partial<UserDeletedEvent>;
}): UserDeletedEvent;
function eventSampler(args: {
event: "SendEmailEvent";
override?: Partial<SendEmailEvent>;
}): SendEmailEvent;
function eventSampler(args: {
event: "UserCreatedEvent";
override?: Partial<UserCreatedEvent>;
}): UserCreatedEvent;
function eventSampler(): {} {
return {};
}
export type EventSampler = typeof eventSampler;

This makes the function sampleEventData fun to use.

FInally, to test our event handlers, we create a MemoryEventBus which enables consuming the same events that are published. See an example.