UNPKG

factory-bot-ts

Version:

A simple library for setting up TypeScript objects as test data - heavily inspired by the awesome Ruby's factory_bot

295 lines (231 loc) 7.25 kB
# factory-bot-ts A simple library for setting up [TypeScript](https://www.typescriptlang.org/) objects as test data - heavily inspired by the awesome Ruby's [factory_bot](https://github.com/thoughtbot/factory_bot). - Fully written in [TypeScript](https://www.typescriptlang.org/) - With (optional) type checking - With no persistence layer - And no promises. ☺️ ## Installation **1.** Add to your project ```sh npm i -D factory-bot-ts yarn add factory-bot-ts --dev ``` ## Basics **1.** Ok, suppose we've got a Ninja model.. ```typescript // ../src/models/ninja.model.ts export enum NinjaRank { GENIN = 'Genin', CHUUNIN = 'Chuunin', JONIN = 'Jonin' } export class Ninja { id?: number name?: string username?: string level?: NinjaRank sensor?: boolean constructor(attrs?: Partial<Ninja>) { Object.assign(this, attrs) } } ``` **2.** We would define our factories.. ```typescript // ../src/tests/index.ts import * as Faker from 'faker' import { sample } from 'lodash' import { FactoryBot } from 'factory-bot-ts' import { Ninja, NinjaRank, Village } from '../src/models' FactoryBot.define('ninja', { id: () => Faker.random.number(), name: () => Faker.name.findName(), username: () => FactoryBot.seq(seq => `${Faker.internet.userName()}_${seq}`), level: () => FactoryBot.rand(NinjaRank), sensor: () => sample([true, false]) }, Ninja) FactoryBot.define('village', { id: () => Faker.random.uuid(), name: () => Faker.name.findName(), members: () => FactoryBot.buildList<Ninja>('ninja', 2) }, Village) export { FactoryBot } ``` **3.** And then we'd just use them on our tests! ```typescript // ../src/models/ninja.model.spec.ts import { FactoryBot } from '../src/tests' import { Ninja, NinjaRank, Village } from '.' export class NinjaSpec { let instance: Ninja before(() => { instance = FactoryBot.build('ninja', { name: 'Kakashi Hatake' }) }) it('builds a Ninja! 👹', () => { expect(instance).to.be.an .instanceof(Ninja) }) } ``` ## More Factory-bot-ts also allow us to.. **1.** Define untyped factories with static data ```typescript FactoryBot.define('ninja', { id: 1, name: 'Sasuke Uchiha', username: 'sasuke', level: NinjaRank.GENIN, sensor: false, sharingan: true }) FactoryBot.build('ninja') /* => { id: 1, name: 'Sasuke Uchiha', username: 'sasuke', level: 'Genin', sensor: false, sharingan: true } */ ``` **2.** Define factories with type checking ```typescript FactoryBot.define<Ninja>('ninja', { id: 1, name: 'Sasuke Uchiha', username: 'sasuke', level: NinjaRank.GENIN, sensor: false }, Ninja) FactoryBot.build('ninja') /* => Ninja { id: 1, name: 'Sasuke Uchiha', username: 'sasuke', level: 'Genin', sensor: false } */ ``` **3.** Define factories with Dynamic data ```typescript FactoryBot.define('ninja', { id: () => Faker.random.number(), name: () => Faker.name.findName(), username: () => Faker.internet.userName(), level: () => FactoryBot.rand(NinjaRank), sensor: () => sample([true, false]) }, Ninja) FactoryBot.build('ninja') /* => Ninja { id: 43748, name: 'Martine Romaguera MD', username: 'Kaleb_Homenick', level: 'Jonin', sensor: true } */ ``` **4.** Define factories with custom, random and sequenced data ```typescript FactoryBot.define('ninja', { id: () => Faker.random.number(), name: () => Faker.name.findName(), username: () => FactoryBot.seq(seq => `${Faker.internet.userName()}_${seq}`), level: () => FactoryBot.rand(NinjaRank), sensor: () => sample([true, false]) }, Ninja) FactoryBot.build<Ninja>('ninja', { name: 'Uzimaki Naruto' }) /* => Ninja { id: 11941, name: 'Uzimaki Naruto', username: 'Art_Crist36_1', level: 'Genin', sensor: true } */ FactoryBot.build<Ninja>('ninja', { name: 'Sasuke Uchiha', username: 'sasuke-kun' }) /* => Ninja { id: 52565, name: 'Sasuke Uchiha', username: 'sasuke-kun', level: 'Chuunin', sensor: false } */ ``` **5.** Define chained factories ```typescript FactoryBot.define('ninja', { id: () => Faker.random.number(), name: () => Faker.name.findName(), username: () => FactoryBot.seq(seq => `${Faker.internet.userName()}_${seq}`), level: () => FactoryBot.rand(NinjaRank), sensor: () => sample([true, false]) }, Ninja) FactoryBot.define('village', { id: () => Faker.random.uuid(), name: 'Leaf', members: () => FactoryBot.buildList<Ninja>('ninja', 2) }, Village) FactoryBot.build('village') /* => Village { id: '7ec17407-cfdb-4a3f-b434-de788eb41591', name: 'Leaf', members: [ Ninja { id: 11941, name: 'Herta Hane', username: 'Kaleb_Homenick_5', level: 'Genin', sensor: true }, Ninja { id: 52565, name: 'Corbin Koss', username: 'Art_Crist36_6', level: 'Genin', sensor: false }] } */ ``` **6.** Extend existing factories in order to generate specialized data ```typescript FactoryBot.define<Ninja>('ninja', { id: 1, name: 'Kakashi Hatake', username: 'kakashi', level: NinjaRank.GENIN, sensor: false }, Ninja) FactoryBot.extend<Ninja>('ninja', 'jōnin', { level: NinjaRank.JONIN }) FactoryBot.build<Ninja>('ninja') /* => Ninja { id: 1, name: 'Kakashi Hatake', username: 'kakashi', level: Genin, sensor: false } */ FactoryBot.build<Ninja>('jōnin') /* => Ninja { id: 1, name: 'Kakashi Hatake', username: 'kakashi', level: Jōnin, sensor: false } */ ``` For more examples, please, check out the project's [specs](https://github.com/roalcantara/factory-bot-ts/blob/master/tests/factory-bot.spec.ts). ## Dependencies To run this project we need to have: - [Node](http://nodejs.org) - [Yarn](http://yarnpkg.com) ## Development 1. Install the dependencies above 2. `$ git clone https://github.com/roalcantara/factory-bot-ts.git` - Clone the project 3. `$ cd factory-bot-ts` - Go into the project folder 4. `$ yarn` - Run the setup script ## Running specs `$ yarn test` to run the specs ## How to contribute - Bug reports and pull requests are welcome on [GitHub](https://github.com/roalcantara/factory-bot-ts) - Follow the [Semantic Versioning Specification](http://semver.org/) - Follow the [GitHub Flow](https://guides.github.com/introduction/flow/) - Follow the [5 Useful Tips For A Better Commit Message](https://robots.thoughtbot.com/5-useful-tips-for-a-better-commit-message) article and the [How to Write a Git Commit Message](http://chris.beams.io/posts/git-commit/) post - Use [Commitizen cli](http://commitizen.github.io/cz-cli/) when committing ## Code of Conduct Everyone interacting in the factory-bot-ts project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/roalcantara/factory-bot-ts/blob/master/CODE_OF_CONDUCT.md). ## License The package is available as open source under the terms of the [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/).