npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

fakingoose

v3.0.0

Published

Data mocker for mongoose schema

Downloads

21,677

Readme

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.
    • options.\<propertyName\>.size <int>: (Array values only) When specified, will ensure that said array field has given number of elements. By default, this is set to 2.

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":"[email protected]",
    "_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
    }
});

Generating a variable-sized array of items per field

When generating array values, you can specify a size parameter to ensure the array field has that many elements. By default, this is set to 2.

Example: Each new user will now have 10 new statuses to start.

const userSchema = new mongoose.Schema({
    email: String,
    name: {
        type: String,
    },
    activities: [{
        type: String,
    }],
});

const userFactory = factory(userSchema, {
    activities: {
        size: 10
    }
});

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 | Supported | | ------- | ------------------ | | 7.x | :white_check_mark: | | 6.x | :white_check_mark: | | 5.x | :white_check_mark: | | 4.x | :white_check_mark: |