Skip to content

Instantly share code, notes, and snippets.

@GregOnNet
Last active April 16, 2018 07:25
Show Gist options
  • Save GregOnNet/0f94e7bba1071dca607e5e70d3954ecb to your computer and use it in GitHub Desktop.
Save GregOnNet/0f94e7bba1071dca607e5e70d3954ecb to your computer and use it in GitHub Desktop.
G.rab - Generic test data generator written in TypeScript

G.rab

Inspired by FakeItEasy

This small framework has the goal to generate test data more efficient. It should reduce the boilerplate for tests arranging the test. There are Plans providing default values for a certain model.

Plan

It is recommended to put all plans you create in a own directory. This makes your test data easy to discover.

To define a plan make use of the base class Plan. Then you need to implement a constructor. You will see that a super call is needed. This ensures that you pass some default data baseed on your model.

No worries the constructor is typed meaning that you get informed if you pass an invalid object.

import { Plan } from './grab';
import { Customer } from './models';

export class CustomerPlan extends Plan<Customer> {
  constructor() {
    super({
      firstName: 'Steven',
      lastName: 'Hawking'
    });
  }
}

After creating a plan you are able to access the generated test data by using the mehtod model();

import { CustomerPlan } from './plans';

const customerPlan = new CustomerPlan();
const customer = customerPlan.model();

A plan also allows you to override the default values. The mehtod model(overrides?: T): T takes an optional parameter allowing you to specify concrete test data.

import { CustomerPlan } from './plans';

const customerPlan = new CustomerPlan();
const customer = customerPlan.model({ firstName: 'Elon' });

Notice that the method model() is typed which saves you from passing invalid properties.

import { CustomerPlan } from './plans';

const customerPlan = new CustomerPlan();
const customer = customerPlan.model({ astName: 'Musk' });
//                                    ^-- error

Generator

In order to reduce the boilerplate of your test data even more the factory G can generate your Plans on the fly.

import { G } from './grab';
import { CustomerPlan } from './plans';

const customer = G.rab(CustomerPlan).model();

You still have the possibility to override custom values.

import { G } from './grab';
import { CustomerPlan } from './plans';

const customer = G.rab(CustomerPlan)
  .model({
    firstName: 'Laura',
    lastName: 'Seiler'
  });
import { OverwritablePlan } from './overwritable-plan';
/**
* Takes a Plan (@see Plan) and creates a instance of it.
* This class is used to provide a more comfortable way creating test data.
*
* @example
* import * Plan from 'testing/plans'
* const pruductPlan = G.rab(Plan.Product)
* const product = productPlan.model;
*/
export class G {
static rab<Model, Plan extends OverwritablePlan<Model>>(plan: (new () => Plan)): Plan {
return new plan();
}
}
export * from './g';
export * from './plan';
/**
* A plan simplifies the way creating test data.
* Plans can be used by @see G which is a factory creating plans.
*/
export interface OverwritablePlan<T> {
/**
* Allow to override the default values of the model
*/
model(overrides?: { [key in keyof T]?: T[key] } ): T;
}
import { OverwritablePlan } from './overwritable-plan';
export class Plan<T> implements OverwritablePlan<T> {
constructor(private defaultModel: T) {}
model(overrides?: { [key in keyof T]?: T[key] }): T {
return {
...this.defaultModel,
...overrides
};
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment