Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

mocker-data-generator

danibram15.7kMIT3.0.3TypeScript support: included

A simplified way to generate mock data, builds using a simple schema and with the FakerJs

mock, data, faker, fakerjs, chance, chancejs, casual, randexp, json, fake, mocks, massive, generator

readme

mocker-data-generator Tweet

npm versionGitHub license

Linux Build statusWindows Build statusCodecov coverageCodecov coverage

GitHub licenseAwesome license

Support link

A simplified way to generate massive mock data based on a schema, using the awesome fake/random data generators like (FakerJs, ChanceJs, CasualJs and RandExpJs), all in one tool to generate your fake data for testing.

Now the library has been migrated 100% to typescript typing are included.

You can test online here: https://danibram.github.io/mocker-data-generator/

Getting started

Install the module and the awesome generator you want: npm install mocker-data-generator faker

Import it

var mocker = require('mocker-data-generator').default // (vanilla way)
var faker = require('faker')


// or

import mocker from 'mocker-data-generator' // (ES6 or Typescript way)
import * as faker from 'faker'

Then use it:

var user = {
    firstName: {
        faker: 'name.firstName()'
    },
    lastName: {
        faker: 'name.lastName()'
    },
    country: {
        faker: 'address.country()'
    },
    createdAt: {
        faker: 'date.past()'
    },
    username: {
        function: function () {
            return (
                this.object.lastName.substring(0, 5) +
                this.object.firstName.substring(0, 3) +
                Math.floor(Math.random() * 10)
            )
        }
    }
}
var group = {
    description: {
        faker: 'lorem.paragraph()'
    },
    users: [
        {
            function: function () {
                return this.generators.faker.random.arrayElement(this.db.user)
                    .username
            },
            length: 10,
            fixedLength: false
        }
    ]
}
var conditionalField = {
    type: {
        values: ['HOUSE', 'CAR', 'MOTORBIKE']
    },
    'object.type=="HOUSE",location': {
        faker: 'address.city()'
    },
    'object.type=="CAR"||object.type=="MOTORBIKE",speed': {
        faker: 'random.number()'
    }
}

// Using traditional callback Style

mocker()
    .addGenerator('faker', faker)
    .schema('user', user, 2)
    .schema('group', group, 2)
    .schema('conditionalField', conditionalField, 2)
    .build(function (error, data) {
        if (error) {
            throw error
        }
        console.log(util.inspect(data, { depth: 10 }))

        // This returns an object
        // {
        //      user:[array of users],
        //      group: [array of groups],
        //      conditionalField: [array of conditionalFields]
        // }
    })

// Using promises

mocker()
    .addGenerator('faker', faker)
    .schema('user', user, 2)
    .schema('group', group, 2)
    .schema('conditionalField', conditionalField, 2)
    .build()
    .then(
        data => {
            console.log(util.inspect(data, { depth: 10 }))
            // This returns an object
            // {
            //      user:[array of users],
            //      group: [array of groups],
            //      conditionalField: [array of conditionalFields]
            // }
        },
        err => console.error(err)
    )

// Synchronously

// This returns an object
// {
//      user:[array of users],
//      group: [array of groups],
//      conditionalField: [array of conditionalFields]
// }
var data = mocker()
    .addGenerator('faker', faker)
    .schema('user', user, 2)
    .schema('group', group, 2)
    .schema('conditionalField', conditionalField, 2)
    .buildSync()

console.log(util.inspect(data, { depth: 10 }))

NOTE: For the demo above you will also need to import util i.e. var util = require('util') or import util from 'util'

Documentation

Data generation goes with model based composed by generators, the generators can have access to the data generated and to the entity generated. Generators run synchronously, take care of the related entities!!

Methods

  • addGenerator(name, generator, runFn): Add a new generator, now generators are not included in the package, so you have to add whathever generator you want.

    • name (String): key of the generator this should match with the key in the schema.
    • generator (library): Library if the generator
    • runFN (function) (Optional) (generator: any, input: any) => any : It compose a exec function for the selected generator, only for custom generators, see randexp in the examples folder
  • schema(name, schema, generationType): Add a new schema, you must specify this params:

    • name (String): Name of the schema.
    • schema (JSON): The schema you define
    • generationType (integer or JSON): In this field you specify how you will generate this schema. 3 ways:
      • Integer to specify how many objects of this schema you want.
      • JSON with this object {max: '<maximunValues>'} you can also optionally pass min {max: '<maximunValues>', min: '<minimumValues>', this will generate a range of objects of this schema, between (0 and max) or (min and max) randomly.
      • JSON with this object {uniqueField: '<yourUniqueField>'} this means that this field (<yourUniqueField>) is an array and you want to generate entities with this unique values
  • reset(): Clean the internal DB.

  • restart(): Clean the internal DB and all the schemas inside.
  • build(callback): This methods start to produce the data and wrap it to the callback function, the callback funtion have 2 parameters, error and data generated.
  • buildSync(): Synchronous version of build(callback). Returns generated data or throws an error.

Schema definition

Every schema should contains the specified fields. Key can be 2 types:

  • Normal string key: indicates the key.
  • Commaseparated string key: indicates that there is a conditional, before the comma you must specify a conditional (you have all level fields generated in this moment), then you must specify the field if the conditional is true see the example.

Inside every value you can put:

  • static: For fixed fields

    {
        static: 'hello im fixed field'
    }
  • self: get himself object, and evaluate the string, so you can get calculated fields.

    • eval (Optional): Also now you can pass, eval to true, to use like in versions < 2.6.0
```javascript
{
    self: 'id'
}   //will get the id of the generated entity

{
    self: 'id',
    eval: true
}   // will get the first user id
```
  • db: get the db, and evaluate the string, so you can access to this entities.

    • eval (Optional): Also now you can pass, fast to true, eval to true, to use like in versions < 2.6.0
```javascript
{
    db: 'user[0].id'
}   // will get the first user id

{
    db: 'user[0].id',
    eval: true
}   // will get the first user id
```
  • eval: evaluate the current string, remember that all context are injected (generators, db the actual object). With this eval field, you must pass an exactly JSON syntax:

    {
        eval: 'object.id'
    }
    
    // OR
    
    {
        eval: 'db.user[0]'
    }
    
    // OR
    
    {
        eval: 'faker.lorem.words()'
    }
  • hasOne: You can pass 2 parameters:

    • hasOne: the name of the related entity, get one random.
    • get (Optional): String that will be evaluated over the random related entity.
    • eval (Optional): Only affects if get is passed, the get param only support dotted paths, with eval=true you can use an eval string, this impacts on the performance

      `javascript

      {
          hasOne: 'user'
      }   // this populate the field with one random user
      
      // OR:
      
      {
          hasOne: 'user',
          get: 'id'
      }   // this populate the field with one id of a random user
        // OR:

        {
            hasOne: 'user',
            get: 'id',
            eval: true
        }   // this populate the field with one id of a random user with eval string
    ```
  • hasMany: You can pass 4 parameters:

    • hasMany: the name of the related entity, get one random.
    • amount (Optional): Fixed number of related entities to get.
    • min (Optional): Minimum entities to get, buy default is 1, if you want the chance to have empty arrays please specify min to 0.
    • max (Optional): Maximum entities to get.
    • get (Optional): String that will be evaluated over the random related entity.
    • eval (Optional): Get will only support dotted paths, with eval= true you can get from an evaluable string
    • unique (Optional): hasMany will get unique values from the entity (Make sure that you have many unique data in the source)

      `javascript

      // In this case we will get 1 user (hasMany)
      {
          hasMany: 'user'
      }   // this populate the field with one random user
      
      // OR:
        {
            hasMany: 'user',
            amount: 1, //optional
        }   // In this case we will get 1 (amount) user (hasMany)

        // OR:

        {
            hasMany: 'user',
            max: 3 // optional
        }   // In this case we will get as max 3 (max) users (hasMany)

        // OR:


        {
            hasMany: 'user',
            min: 1 //optional
            max: 3 //optional
        }   // In this case we will get bettween min 1 (min) and max 3 (max) users (hasMany)

        // OR:

        {
            hasMany: 'user',
            get: 'id'
        }   // In this case we will get the id (get) from 1 random user (hasMany)
    ```
  • incrementalId: For incremental numeric ids, pass the start number to increment. If you put incrementalId = true it takes from 0 the ids.

    {
        incrementalId: 0
    }
  • function: No params are passed, only context (this), in this you have {db, object, faker, chance}, and you can use faker or chance functions, object (the specified model), db (actual data generated)

          { function: function(){
    
              // this.db
              // this.object
              // this.generators
    
              return yourValue
          } }
    
          // OR:
    
          { function(){
    
              // this.db
              // this.object
              // this.generators
    
              return yourValue
          } }
  • [Array]: you can pass an array that indicates an array of data you can create, passing in the first field the generator (function, faker, or array(not Tested)), and in the second field pass a config object (length, fixedLentgh)

    • length: to know how many values
    • fixedLength (Optional): true to create always same amount of values in the array, false to generate a random number between 0 and 'length' value. False by default.
    • concat (Optional): An stringuified array ex: '[object.id, db.users.id]'. This should be an evaluable string to concat with the array that are generating. Also takes in mind that if you have a fixedLength, should not increase the length.
    • strictConcat (Optional): true to remove duplicates in the concatenated string array, when it is calculated. False by default.

      [{
         // Any generator
             // Faker
         [name of the generator injected]: 'path inside the generator'
             // If faker is injected with .addGenerator('faker', faker) then you can use:
         faker: 'random.arrayElement(db.users).userId'
             // Function that has included index, length and self that refers at the actual array generation
         function: function (index, length, self){ return /**/ }
      
         // Array config
         length: 10,
         fixedLength: true
      
         // Concat
         concat: '[db.users[0].userId, db.users[1].userId]'
         strictConcat: true
      }]

Custom generators

It happens!Mocker now is independant of the generators so I hope this will give you more freedom. This is an example that you can check on the examples folder, where 2 generators are used:

    var mocker = require('../build/main').default
    var faker = require('faker')
    var Randexp = require('randexp')
    var util = require('util')

    var user = {
        firstName: {
            faker: 'name.firstName()'
        },
        notes: {
            randexp: /hello+ (world|to you)/
        }
    }

    mocker()
        .addGenerator('faker', faker)
        .addGenerator('randexp', Randexp, function (generator, input) {
            return new generator(input).gen()
        })
        .schema('user', user, 2)
        .build(function (error, data) {
            if (error) {
                throw error
            }
            console.log(util.inspect(data, { depth: 10 }))
        })

Optional fields

  • [virtual]: Boolean, if you pass this option, this mean that this field will not appear at the output entity. But you can use during the generation.
    {
        // Any generator
            // Faker
        [name of the generator injected]: 'path inside the generator'
            // If faker is injected with .addGenerator('faker', faker) then you can use:
        faker: 'random.arrayElement(db.users).userId'
            // Static
        static: 'any static field'
            // Function
        function: function (){ return /**/ }

        // With the virtual option
        virtual: true

    }

Data generation

Initialize mocker with the config, and then generate any entity with promises style, use generate function that accepts the name of the model and the amount of data to generate. Like the example:

mocker()
    .addGenerator('faker', faker)
    .schema('user', user, 2)
    .schema('group', group, 2)
    .schema('conditionalField', conditionalField, 2)
    .build(function(err, data) {
        console.log(util.inspect(data, { depth: 10 }))
        // This returns an object
        // {
        //      user:[array of users],
        //      group: [array of groups],
        //      conditionalField: [array of conditionalFields]
        // }
    })

You can also pass instead of the number, an object with the a config, from now {uniqueField}. If this field exists tells to the generator that instead of init a fixed length of data, generate an amount of data depending of the values of the field you will specify. You have 2 way to deal with this, check the examples See the output of this example:

//
// First way, using an 'values' embedded object
//

var cat = {
    name: {
        values: ['txuri', 'pitxi', 'kitty']
    }
}
var m = mocker()
    .addGenerator('faker', faker)
    .schema('cat', cat, 10)
    .schema('cat2', cat, { uniqueField: 'name' })
    .build(function(err, data) {
        console.log(util.inspect(data, { depth: 10 }))
    })

//
// Second way, without 'values' embedded.
//

var cat = {
    name: ['txuri', 'pitxi', 'kitty']
}
var m = mocker()
    .addGenerator('faker', faker)
    .schema('cat', cat, 10)
    .schema('cat2', cat, { uniqueField: 'name' })
    .build(function(err, data) {
        console.log(util.inspect(data, { depth: 10 }))
    })

eval Option (Beta):

In version >= 2.6.0, eval option was introduced to run mocker-data-generator like olders versions, so by default is running without eval: faker, chance, casual, hasMany, hasOne, db and self. This means that this methods loose habilities, when eval is not passed, but this are the speed results with eval active (old way) and without (new way)

faker eval old:  0.969ms
faker now:       0.215ms
chance eval old: 0.559ms
chance now:      0.099ms
casual eval old: 0.360ms
casual now:      0.026ms

More, Coming soon

Online API

You can visit the repo url here: https://github.com/danibram/mocker-api-tester

Or visit the api directly: https://mocker-api.herokuapp.com/

Development

Run npm install;npm run dev to watch the project, webpack compile the code automatically. Run npm build to build the normal and minified version.

Why not use json-schema-faker?

json-schema-faker is awesome and works really nice, but i need a simplified and fast way to generate mock data for my projects, so i created this.

Credits

I couldn't do this without this awesome libraries, so thanks to all:

License

Licensed under the MIT license. 2022

changelog

Changelog

All notable changes to this project will be documented in this file. See standard-version for commit guidelines.

3.0.3 (2023-04-22)

3.0.2 (2023-04-22)

3.0.1 (2022-12-30)

3.0.0 (2022-12-30)

Breaking changes!

  • generators: Now mocker remove thirdparty generators from it. Now you should provide to the library, check the readme
  • string-parser: Now to unify logic, and reduce complexity. The fast eval function not call the function. So if in the past with faker you use: lorem.paragraph now its important to use lorem.paragraph() because eval function is not doing more magic than the necesary

Thank you all for you patient, this release was planned maybe a year ago, but I didnt have time to work on it.

2.12.0 (2021-02-03)

Features

  • chore: updated deps

2.10.0 (2020-10-13)

Features

  • Merged Array Example: #102
  • Merged Generic Type for Generator: #114

2.9.0 (2020-09-04)

Features

  • add buildSync method to Mocker class (772b20d)
  • all deps updated!!

Bug Fixes

  • appveyor: update matrix config to install defined node version (703aa41)
  • docs-website: added seed example (d1fa143)

2.8.0 (2020-05-13)

Features

  • chore: easy publish as minor shortcut (fd1a87b)
  • chore: update chance and tslib, and some devDependencies (59d0aea)
  • Mocker.seed: add posibility to prepopulate the db. Thanks @suspiciousfellow and @marshallswain for the idea and the code (dfb2ad6)
  • Mocker.seed: add tests (7faafab)
  • Mocker.seed: seed and schema and work together (68970fc)

2.7.0 (2020-04-16)

All deps updated!

2.6.6 (2018-09-18)

Feature

Unique field in hasMany generator

Bug Fixes

  • errors: hasMany added unique error

All deps updated!

2.6.5 (2018-09-06)

All deps updated!

2.6.4 (2018-05-08)

Bug Fixes

  • hasOne: Issues with eval (f1ab9e8)

2.6.3 (2018-05-08)

2.6.2 (2018-05-08)

Bug!

  • Fixing bug related to eval!

2.6.1 (2018-03-20)

Improvements!

  • Now I rework internal part of the generators to offer the posibility of avoid eval step, i used eval to offer the maximum flexibility, but now its optional, of course that without eval, is less flexible, but if it fits for your mock data right now you will gain 10x speed, Awesome! Also it offers the posibility of use eval like in the older versions of mocker.

Welcome to the ludicrous speed! 🎉

2.5.2 (2018-01-17)

Bug Fixes

  • generation: added fix when min = 0 in hasMany, now can produce empty array of data, by default is 1, so you have to specify minimum to 0 in order to have the chance to produce empty arrays (7f97646)

All deps updated!

2.5.0 (2017-11-01)

Breaking Changes!

  • Now the build method throws the error, in the case of the callback in a traditional style function function(err, data) in the case of promise style in the reject.

Bug Fixes

  • test: separate gh-pages generation modules from the mocker modules for development, some test fails (2cc421e)
  • Better error throwing and test covered (20ca0a0)

Bug Fixes

  • test: separate gh-pages generation modules from the mocker modules for development, some test fails (2cc421e)
  • Better error throwing and test covered (20ca0a0)

2.4.9 (2017-10-20)

Features

  • Added browser build
  • Fixes in build to sync with gh-pages

2.4.5 (2017-10-20)

2.4.4 (2017-10-17)

Bug Fixes

  • fakerjs: Better locale detector and better testing (f05872d)

2.4.3 (2017-10-16)

2.4.2 (2017-10-16)

2.4.1 (2017-10-16)

2.4.0 (2017-10-16)

Bug Fixes

  • builder: fix tslint space identation (b3f9f7c)

Features

  • fakerjs: Added multilanguaje support (0b94471)
  • fakerjs: Added tests for multilang support (5078d24)
  • fakerjs: Updates on the readme (b79e88f)

2.3.0 (2017-10-16)

Bug Fixes

  • builder: fix tslint space identation (b3f9f7c)

Features

  • fakerjs: Added multilanguaje support (0b94471)
  • fakerjs: Added tests for multilang support (5078d24)
  • fakerjs: Updates on the readme (b79e88f)

2.2.1 (2017-10-13)

Bug Fixes

  • linter: trying to use supported tslint rule (5edac70)
  • updates: Update libs to last releases (a6ce60b)

2.2.0 (2017-06-14)

Features

2.1.0 (2017-05-27)

Features

2.0.2 (2017-05-24)

Bug Fixes

  • browserify: fix browserify builds changing casual to browserify-casual (de93262)

2.0.1 (2017-05-24)

Changes

  • fix: tslib fix for ES5 builds
  • updates: updates on dependencies

2.0.0 (2017-03-18)

Features

  • build: new build using Typescript, breaking change in imports, adapted import to be used with es6 (6114eaf)

OLD Release History

(1.2.7)

  • Fix little issue with array generators, now parse well the index inside, add a test for that
  • Fix string issue with fakerJs
  • Fixed babel polyfill issues
  • updates on dev packages

(1.2.2)

(1.2.1)

  • Start to parse better the errors

(1.2.0)

  • New internal reorganization
  • Added hasOne (related is deprecated) and hasMany
  • Breaking Change: related config is deprecated, instead of related use hasOne.

(1.1.1)

  • Added RandExpJs generator
  • Improve test system (I know im improving it! =P)
  • Breaking Change: the older versions aren´t compatible with this module, the way to generate the data are changed:

    (1.1.0)

  • Added casualJs
  • Added self option
  • Added db option
  • Added related option

(1.0.6)

  • Updated chance.js to 1.0

(1.0.5)

  • Added the concat option, and the strictConcat on Array generator.

(1.0.4)

  • Added on uniqueField two ways to generate the data
  • Starting to add errors

(1.0.3)

  • Fix Arrays
  • Breaking Change: the older versions aren´t compatible with this module, the way to generate the data are changed:

    var cat = {
        name: {
            values: ['txuri', 'pitxi', 'kitty']
        }
    }
    var m = mocker()
        .schema('cat', cat, 10)
        .schema('cat2', cat, { uniqueField: 'name' })
        .build(function (data) {
            console.log(util.inspect(data, { depth: 10 }))
        })

(0.7.0)

  • Breaking Change: Added the posibility to enable the pluralize on the output entity. Now if you want to pluralize the output follow the example in the doc, by defatult is not anymore pluralized.

    Old call configuration:

    var m = mocker(config)
    m.generate('user', 2)
        .then(m.generate('group', 2))
        .then(m.generate('conditionalField', 2))
        .then(function (data) {
            console.log(util.inspect(data, { depth: 10 }))
            //This returns an object
            // {
            //      user:[array of users],
            //      group: [array of groups],
            //      conditionalField: [array of conditionalFields]
            // }
        })

    New array configuration:

    var m = mocker(config)
    m.generate('user', 2)
        .generate('group', 2)
        .generate('conditionalField', 2)
        .build(function (data) {
            console.log(util.inspect(data, { depth: 10 }))
            //This returns an object
            // {
            //      user:[array of users],
            //      group: [array of groups],
            //      conditionalField: [array of conditionalFields]
            // }
        })

(0.6.0)

  • Breaking Change: Added the posibility to enable the pluralize on the output entity. Now if you want to pluralize the output follow the example in the doc, by defatult is not anymore pluralized.

(0.5.0)

  • Breaking Change: Break Point with array config. Now is more clear.

    Old array configuration:

        [{
            //Any generator
                //Faker
            faker: 'random.arrayElement(db.users)[userId]'
                //Chance
            chance: 'integer'
                //Function
            function: function (){ return /**/ }
    
        }, //Array config
        {length: 10, fixedLength: false}]

    New array configuration:

        [{
            //Any generator
                //Faker
            faker: 'random.arrayElement(db.users)[userId]'
                //Chance
            chance: 'integer'
                //Function
            function: function (){ return /**/ }
    
            //Array config
            length: 10,
            fixedLength: false
        }]

(0.4.7)

  • Add virtual fields

(0.4.5)

  • Add incrementalId config
  • Some tweaks on dev config to start to use generators on typescript
  • Performance tweaks for large data generation

(0.4.1)

  • Show in console the errors. (I will improve this)
  • Add support to chanceJs, exactly like FakerJs (see "Model definition" Chance)

(0.3.0)

  • Fix errors on iteration over nested structures (new improved interator)
  • Added support to call more naturally to FackerJs fields (see "Model definition" Faker)

(0.2.2)

  • Added a pluralization function
  • Fixed a little issue with the roots schemas (now you can do really crazy things, see test/mocker.example.js)
  • Fix errors introduced in 0.2.0

(0.1.6)

  • Fix an error: (Clean initial data field)
  • Fix some memory errors adding inmutableJS for the model
  • Add new tests

(0.1.1)

  • Real Refractor of the code
  • Add support multi-level schemas
  • Add tests
  • Add travis support

(0.0.4)

  • First release i will update soon with tests and more examples, stay tuned!