Skip to content

Instantly share code, notes, and snippets.

@stevehanson
Last active January 11, 2019 16:25
Show Gist options
  • Save stevehanson/ce73bd1bb9fa599243e44cf19e99140e to your computer and use it in GitHub Desktop.
Save stevehanson/ce73bd1bb9fa599243e44cf19e99140e to your computer and use it in GitHub Desktop.
Typescript Factories
import { times, upperFirst } from 'lodash';
type GeneratorFnOptions = {
sequence: number;
};
type GeneratorFn<T> = (opts: GeneratorFnOptions) => T;
type GeneratorsMap = {
[key: string]: GeneratorFn<any>;
};
class FactoryClass {
generators: GeneratorsMap = {};
define<T>(name: string, generator: GeneratorFn<T>) {
this.generators[name] = generator;
}
build<T>(name: string, options: Partial<T>): T {
return {
...this.generators[name]({ sequence: nextId() }),
...options,
};
}
buildList<T>(number: number, name: string, options: Partial<T>): T[] {
return times(number, () => {
return this.build<T>(name, options);
});
}
}
export const Factory = new FactoryClass();
import { snakeCase } from 'lodash';
import Factory from 'factories-library';
import { User } from 'lib/types';
// User of the library define factories like this:
Factory.define<User>('user', ({ sequence }) => {
const name = 'Bill Bob';
return {
id: sequence,
fullName: name,
username: snakeCase(name),
createdAt: Date.now(),
};
});
// Factories are used like this:
// TODO, need mechanism to autoload all factories before tests
import Factory from 'factories-library';
import { User } from 'lib/types';
describe('factories', () => {
test('work', () => {
const user = Factory.build<User>('user', { username: 'susan' });
// alternatively, trying to simplify usage to something like (no luck yet with typings):
// const user = Factory.createUser({ username: 'susan' })
expect(user.fullName).toEqual('Bill Bob');
expect(user.username).toEqual('susan');
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment