Skip to content

faboulaws/fakingoose

master
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Code

Latest commit

 

Git stats

Files

Permalink
Failed to load latest commit information.
Type
Name
Latest commit message
Commit time
 
 
lib
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

fakingoose

Build Status Coverage Status

An automatic mock data generator for mongoose using schema definition.

Install


npm install fakingoose

Usage

const {
    factory
} = require('fakingoose');
const entityFactory = factory(model, options);

factory(model, options)

  • model <Schema> or <Model>: Mongoose model or schema.
  • options <? Object>: Generation options are optional. The factory would generate data for all fields based on the schema alone. For cases where there is a need for custom values, options can be used to define custom values or data generation setting per field.
    • options.<propertyName>.value <mixed>: A static value for each generated mock object.
    • options.<propertyName>.value: <function> a function for generating a dynamic value per item. This function receives the mock object as first argument.
    • options.<propertyName>.skip <boolean>: When set to true would skip the field.
    • options.<propertyName>.type <string>: The sub-type for this field type. For example <String> schema type supports email , firsname and lastname .
    • options.\<propertyName\>.populateWithSchema: Uses a schema to generate mocks of related models
    • options.\<propertyName\>.populateWithFactory: Uses another factory to generate mocks of related models. This options provides more flexibility than populateWithSchema, taking advantage of custom behaviours of factory via Factory options.

Usage example

const mongoose = require('mongoose');
const {
    factory
} = require('fakingoose');
const {
    Schema
} = mongoose;

const authorSchema = new Schema({
    id: Schema.Types.ObjectId,
    title: {
        type: String,
        enum: ['Mr', 'Mrs', 'Dr']
    },
    fullname: String,
    username: String,
    email: String,
    favoriteQuote: String,
});

const blogSchema = new Schema({
    title: String,
    author: authorSchema,
    body: String,
    comments: [{
        body: String,
        date: Date
    }],
    date: {
        type: Date,
        default: Date.now
    },
    hidden: Boolean,
    meta: {
        votes: {
            type: Number,
            min: 0
        },
        favs: {
            type: Number,
            min: 0
        }
    }
});

const options = {
    author: {
        email: {
            type: 'email',
        },
        username: {
            value: (object) => {
                return object.fullname.toLowerCase().replace(/\s/g, '.');
            }
        },
        favoriteQuote: {
            skip: true
        }
    },
};
const blogFactory = factory(blogSchema, options);

const mock = blogFactory.generate({
    author: {
        fullname: 'John Doe'
    }
});

sample output

{
  "title":"8tnkcjplr",
  "author":{
    "id":"5d513f762a48134adb1868d7",
    "title":"Dr",
    "fullname":"John Doe",
    "username":"john.doe",
    "email":"re@sisuki.mc",
    "_id":"5d513f762a48134adb1868d8"
  },
  "body":"ebjwad6*keskl",
  "comments":[
    {
      "body":"d$*t9y3",
      "date":"2019-08-12T10:29:10.193Z",
      "_id":"5d513f762a48134adb1868d9"
    },
    {
      "body":"jv5o[",
      "date":"2019-08-12T10:29:10.193Z",
      "_id":"5d513f762a48134adb1868da"
    }
  ],
  "hidden":false,
  "meta":{"votes":-3419053502758912,"favs":3323094479405056},
  "_id":"5d513f762a48134adb1868db"
}

Define options for nested properties

To define options for nested a property use the nested property path (property names sperated by a dot). Example:

const options = {
    "meta.votes": {
        value: 0
    }, // set value for 'votes' property under meta
    "meta.favs": {
        skip: true
    } // skip value for 'favs' property under meta
}

Skipping multiple nested properties

Multiple nested properties can be skipped from parent property. Example:

const accountSchema = new mongoose.Schema({
    user: {
        generalInfo: {
            firstName: String,
            lastName: String,
            age: Number
        },
        address: {
            postCode: String,
            street: String
        }
    }
});
const accountFactory = factory(accountSchema, options);

To generate mocks without an address define options as below you have to override the default factory's options:

const options = {
    'user.address': {
        skip: true
    }
}

or

const options = {
    user: {
        address: {
            skip: true
        }
    }
}

then

const mockObject = accountFactory.generate({}, options);

Generating ObjectId values

When generating ObjectId values, you can choose to Stringify the generated ObjectId by using the tostring option. By default this options is true , so all generated ObjectIds would be converted to a String. Set tostring to false to disable this behaviour.

Example: In the snippet below all ObjectIds generated are not stringified.

const friendSchema = new Schema({
    id: Schema.Types.ObjectId,
    friendIds: [{
        type: Schema.Types.ObjectId
    }],
    bestFriend: {
        id: Schema.Types.ObjectId
    }
});

const amigoFactory = factory(friendSchema, {
    id: {
        tostring: false
    },
    friendIds: {
        tostring: false
    },
    'bestFriend.id': {
        tostring: false
    }
});

Global settings

To disable stringification globally use factory.setGlobalObjectIdOptions .

Example:

const friendSchema = new Schema({
    id: Schema.Types.ObjectId,
    friendIds: [{
        type: Schema.Types.ObjectId
    }],
    bestFriend: {
        id: Schema.Types.ObjectId
    }
});

const amigoFactory = factory(friendSchema).setGlobalObjectIdOptions({
    tostring: false
});

Generating mocks for related models (Populate)

Mongoose provides an API for automatically replacing the specified paths in the document with document(s) from other collection(s). This package provides a similar functionality when generating mocks.

An example: In the snippet below we have two schemas, activitySchema & personSchema .

const activitySchema = new mongoose.Schema({
    name: String,
    value: String,
});

const personSchema = new mongoose.Schema({
    email: String,
    name: {
        type: String,
    },
    activities: [{
        type: mongoose.Schema.Types.ObjectId,
        ref: 'activity'
    }],
});

When generating mock data from the personSchema we should get the sample below

{
    email: 'l7@eiwtef%(pzitx',
    name: 'ym](ht7ucas*',
    activities: ['60f1e810a8b8ac392c3869b7', '60f1e810a8b8ac392c3869b8'],
    _id: '60f1e810a8b8ac392c3869b9'
}

In some cases we might want to receive activity data instead of activity ID in the activities property, so we have a structure like below.

 {
     email: ')5b2[dj@@)p91(',
     name: 'qo[jk!',
     activities: [{
             name: '7^*8h^@!zp^!*hqwn',
             value: ']55f$hmva',
             _id: '60f1e51dead56f35c7ed4f62'
         },
         {
             name: 'r!cv!k!p#vqfqt4a9k',
             value: '$@6k!z&oflj6',
             _id: '60f1e51dead56f35c7ed4f63'
         }
     ],
     _id: '60f1e51dead56f35c7ed4f64'
 }

Let's look at two seperate ways we can achieve this:

  • options.\<propertyName\>.populateWithSchema: Uses a schema to generate mocks of related models.

  • options.\<propertyName\>.populateWithFactory: Uses another factory to generate mocks of related models. This options provides more flexibility than populateWithSchema, taking advantage of custom behaviors of factory via Factory options.

Example: options.populateWithFactory

  const activityFactory = mocker(activitySchema)

  const personFactory = mocker(personSchema, {
      activities: {
          populateWithFactory: activityFactory
      }
  })
  const mock = personFactory.generate()

Example: options.populateWithSchema

const myFactory = mocker(schema, {
    activities: {
        populateWithSchema: activitySchema
    }
})
const mock = myFactory.generate()

Generating decimal (Decimal128) values

When generating decimal values, you can choose to Stringify the generated number by using the tostring option. By default this options is true , so all generated numbers would be converted to a String. Set tostring to false to disable this behaviour.

Example: In the snippet below all numbers generated are not stringified.

const productSchema = new Schema({
    price: Schema.Types.Decimal128
});

const productFactory = factory(productSchema, {
    price: {
        tostring: false
    }
});

Global settings

To disable stringification globally use factory.setGlobalDecimal128Options .

Example:

const productSchema = new Schema({
    price: Schema.Types.Decimal128
});

const productFactory = factory(productSchema).setGlobalDecimal128Options({
    tostring: false
});

Override factory options per mock generated

I some cases we want to override options that we used to initialise a factory. These options can be overridden in the generate() method of the factory.

Example

const schema = new Schema({
    updated: {
        type: Date,
        default: Date.now
    },
    title: String,
    content: String,
});

const options = {
    updated: {
        skip: true
    }
};

const myFactory = mocker(schema, options);
const mockWithoutUpdated = myFactory.generate({}); // here use options used to initilize the factory. We skip the "updated: field

const mockWithoutTitle = myFactory.generate({}, { // here use custom options. We skip the "title: field
    title: {
        skip: true
    }
});

Supported Types

  • String
  • Array
  • Number
  • Decimal128
  • ObjectId
  • Boolean
  • Mixed
  • Buffer
  • Embedded
  • Date
  • Map

Mongoose version Support

Version 4.x and 5.x are supported.

About

An automatic mock data generator for mongoose using the schema definition

Resources

License

Stars

Watchers

Forks

Packages

No packages published