A test data factory
A Factory encapsulates creating an object. In TypeScript tests the most popular variant is a simple function with defaults and a Partial override:
export function createCard(overrides: Partial<Card> = {}): Card {
return {
number: '4111111111111111',
holder: 'TEST USER',
expiry: '12/30',
cvv: '123',
...overrides,
};
}
const expired = createCard({ expiry: '01/20' });
This is shorter than a Builder and fully typed: TypeScript won't let you pass a field that isn't in Card.
The second popular form is a factory that not only builds an object but also creates the entity in the system through the API:
export async function createAccountViaApi(
request: APIRequestContext,
overrides: Partial<NewAccount> = {},
) {
const res = await request.post('/api/accounts', {
data: { currency: 'EUR', ...overrides },
});
expect(res.ok()).toBeTruthy();
return (await res.json()) as Account;
}
Such a function is conveniently wrapped in a fixture, to add cleanup after use.
A nuance with spread: overrides with a field set to undefined will overwrite the default with undefined. For nested objects spread is shallow, so nested overrides must be merged separately.
Partial override, which is short and type-safe. Factories that create entities through the API I wrap in fixtures, so cleanup is guaranteed.