1.4.5 • Published 4 years ago

@bluesh55/factory v1.4.5

Weekly downloads
38
License
MIT
Repository
-
Last release
4 years ago

Factory

NPM version

Factory is the library for creating data from pre-configured model definition. It is good to use for testing purposes.

This library is inspired by FactoryBot.

Installation

Node.js:

npm install --save @bluesh55/factory

Getting Started

Create configuration file

First of all, you must run init command for creating a configuration file.

npx factory init

This command will create .factoryrc.json file at the directory where you run the command.

// .factoryrc.json

{
  "modelsDir": "./mytest/factories/",
  "loaderDir": "./tests/helpers"
}
Create loader file

And then, you have to run init:loader command for creating loader file that loads all models at runtime. If you want to writing model using typescript, you can use --typescript option.

# Create loader file (default: Javascript)
npx factory init:loader

# Create loader file (Typescript)
npx factory init:loader --typescript
Create test model

Create your test model at the directory you configured above.

// `./mytest/factories/person.js`
const { Person } = require('../../db/models') // use Sequelize

module.exports = {
  name: 'person',
  specification: {
    id: {
      type: Number,
    },
    name: {
      type: String,
      defaultValue: async seq => {
        return `name{seq}`
      },
    },
    tel: {
      type: String,
      defaultValue: '010-1234-4321',
    },
  },
  creator: attributes => {
    return Person.create(attributes)
  },
}
Use factory at your test file
// example of jest

const { factory } = require('@bluesh55/factory')

describe('Person', () => {
  beforeEach(async done => {
    await factory.create('person')
    await factory.create('person', { name: 'Andrew' })
    /*
       This will create the person in the database like this

       {
          id: 1,
          name: 'name0',
          tel: '010-1234-4321'
       },
       {
          id: 2,
          name: 'Andrew',
          tel: '010-1234-4321'
       }
     */
  })

  it('the test case what you want', done => {
    // ...
  })
})

Configuration

// .factoryrc.json

{
  "modelsDir": "./mytest/factories/",
  "loaderDir": "./tests/helpers"
}
  • modelsDir: The directory path that includes all test models.
  • loaderDir: The directory path that will be created loader file when you run the command npx factory init:loader

Test model

The test model is a definition of what you want to build and how to create to the database(or whatever).
It has some options which be able to create data dynamically from static definition.

name

The test model's name for creating.

// Define mymodel

module.exports = {
  name: 'mymodelname',
  specification: {
    ...
  },
  creator: async (attributes) => {
    ...
  }
}
// Create mymodel

factory.create('mymodelname')

specification

specification is a complicated option that has some sub-options. See below example.

const { encryptPassword } = require('../utils/crypto'); // use custom crypto util to encrypt password

module.exports = {
  name: 'user',
  specification: {
    id: {
      type: Number,
    },
    email: {
      type: String,
      defaultValue: async (seq) => {
        return `email${seq}@gmail.com`
      }
    },
    password: {
      type: String,
      attributeName: 'encrypted_password',
      transform: async (password) => {
        const encryptedPassword = await encryptPassword(password);
        return encryptedPassword;
      },
      defaultValue: 'password',
    },
    username: {
      type: String,
      defaultValue: async (seq) => {
        return `username${seq}`
      }
    },
    tel: {
      type: String,
      defaultValue: '010-1234-4321'
    },
    isAdmin: {
      type: Boolean,
      defaultValue: false,
      attributeName: 'user_type',
      transform: (value) => {
        const newValue = value ? 1: 0;
        return newValue;
      }
    }
  },
  creator: async (attributes) => {
    ...
  }
}
  • type: The type of data. There is nothing using this option yet. Just specification.
  • defaultValue: This is used as a default value if you don't specify attribute when call create method.
    If function or async function is given, defaultValue would be the value of the function returns and get the seq parameter. The seq parameter is sequential number start from 0. This is good to use for uniqueness data.
  • attributeName: This is used if the name of attribute is different between specification key and database column name.
  • transform: In some cases, maybe you want to transform value to something different. In the above example, the password attribute has the transform option to encrypt input value. It can be function or async function that gets old value as parameter. It have to return the transformed data.

creator

The Factory delegates the data creation part to you. You can use Sequelize, Mongoose, whatever to save the data in database.
What you have to do is just defining creator function. If you define creator function, the Factory uses that when you call create method.
The creator function gets an attributes parameter that is derived from specification.

// Define creator function uses sequelize

const { MyModel } = require('../../db/models'); // require Sequelize instance

module.exports = {
  name: 'mymodel',
  specification: {
    ...
  },
  creator: async (attributes) => {
    return await MyModel.create(attributes);
  }
}

And it must return created data if you want to use that in the test.

// And use in the test
describe('...', () => {
  let mymodel;

  beforeEach(async (done) => {
    mymodel = await factory.create('mymodel');
    done();
  });

  ...
})

License

Factory is licensed under the MIT License.

1.4.5

4 years ago

1.4.4

4 years ago

1.4.3

4 years ago

1.4.2

4 years ago

1.4.1

4 years ago

1.4.0

4 years ago

1.2.0

4 years ago

1.3.1

4 years ago

1.3.0

4 years ago

1.1.1

5 years ago

1.1.0

5 years ago

1.0.0

5 years ago

0.0.3

5 years ago

0.0.2

5 years ago

0.0.1

5 years ago