Git Product home page Git Product logo

sequelize-mocking's Introduction

sequelize-mocking

Build StatusDependency Status devDependency Status

Known Vulnerabilities

NPM NPM

Sequelize extension to deal with data-mocking for testing

  • it was tested with Sequelize 3.19.3 before 1.0.0
  • it was tested with Sequelize 4.3.1 since 1.0.0.
  • it was tested with Sequelize 5.3.0 since 2.0.0

And you have to declare in your package.json the expected sequelize version

It will use the sqlite database for mocked database, will recreate it for database.

Can be integrated with Mocha and Jasmine.

A sample of use:

/**
 * Test around the @{UserService}
 *
 * @module test/user/service
 */

'use strict';

const chai = require('chai');
const sinon = require('sinon');
const path = require('path');
const sequelizeMockingMocha = require('sequelize-mocking').sequelizeMockingMocha;

describe('User - UserService (using sequelizeMockingMocha) - ', function () {
    const Database = require('../../lib/database');
    const UserService = require('../../lib/user/service');
    const UserModel = require('../../lib/user/model');

    // Basic configuration: create a sinon sandbox for testing
    let sandbox = null;

    beforeEach(function () {
        sandbox = sinon.sandbox.create();
    });

    afterEach(function () {
        sandbox && sandbox.restore();
    });

    // Load fake data for the users
    sequelizeMockingMocha(
        Database.getInstance(),
        path.resolve(path.join(__dirname, './fake-users-database.json')),
        /* Or load array of files
        [
            path.resolve(path.join(__dirname, './fake-users-database.json')),
            path.resolve(path.join(__dirname, './fake-candy-database.json')),
        ]
        */
        { 'logging': false }
    );

    it('the service shall exist', function () {
       chai.expect(UserService).to.exist;
    });

    describe('and the method findAll shall ', function () {
        it('exist', function () {
           chai.expect(UserService.findAll).to.exist;
        });

        it('shall returns an array of user', function () {
            return UserService
                .findAll()
                .then(function (users) {
                    chai.expect(users).deep.equals([{
                        'id': 1,
                        'firstName': 'John',
                        'lastName': 'Doe',
                        'age': 25,
                        'description': null
                    }]);
                });
        });
    });

    describe('and the method find shall ', function () {
        it('exist', function () {
            chai.expect(UserService.find).to.exist;
        });

        it('shall return a user if we can', function () {
            let findByIdSpy = sandbox.spy(UserModel, 'findById');

            return UserService
                .find(1)
                .then(function (user) {
                    chai.expect(findByIdSpy.called).to.be.true;
                    chai.expect(findByIdSpy.calledOnce).to.be.true;
                    chai.expect(findByIdSpy.calledWith(1)).to.be.true;

                    chai.expect(user).deep.equals({
                        'id': 1,
                        'firstName': 'John',
                        'lastName': 'Doe',
                        'age': 25,
                        'description': null
                    });
                });
        });

        it('shall return null if not found', function () {
            return UserService
                .find(-1)
                .then(function (user) {
                    chai.expect(user).to.be.null;
                });
        });
    });
});

And the mocked data from the JSON file:

[
  {
    "model": "user",
    "data": {
      "id": 1,
      "firstName": "John",
      "lastName": "Doe",
      "age": 25,
      "description": null
    }
  }
]

sequelize-mocking's People

Contributors

codr avatar eduardchai avatar julesgoullee avatar markablov avatar mukopikmin avatar pacoccino avatar peterbecich avatar rochejul avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

sequelize-mocking's Issues

Deprecation warning

I get this warning when using this library

Deprecation warning: moment construction falls back to js Date. This is discouraged and will be removed in upcoming major release. Please refer to moment/moment#1407 for more info.
Arguments: [object Object]
Error
at Function.createFromInputFallback (C:\Users\rmclaughlin\Documents\projects\memories-lambda-fullobituary\node_modules\sequelize-mocking\node_modules\sequelize\node_modules\moment\moment.js:850:105)
at configFromString (C:\Users\rmclaughlin\Documents\projects\memories-lambda-fullobituary\node_modules\sequelize-mocking\node_modules\sequelize\node_modules\moment\moment.js:970:32)
at configFromInput (C:\Users\rmclaughlin\Documents\projects\memories-lambda-fullobituary\node_modules\sequelize-mocking\node_modules\sequelize\node_modules\moment\moment.js:1473:13)
at prepareConfig (C:\Users\rmclaughlin\Documents\projects\memories-lambda-fullobituary\node_modules\sequelize-mocking\node_modules\sequelize\node_modules\moment\moment.js:1456:13)

I am using node ver 4.5.0

Fields UUID not working on creation table

Hello,

In my model definition when I have a field like type: DataTypes.UUID
the table creation with the sync() function crashes with :
{ SequelizeDatabaseError: SQLITE_ERROR: near "BINARY": syntax error

The SQL creation table under sequelize-mocking is :
CREATE TABLE IF NOT EXISTS brands (id CHAR(36) BINARY NOT NULL UNIQUE PRIMARY KEY,

The field id stays as MySQL schema creation (CHAR(36) BINARY) that doesn't seems supported on sqlite (UUID normally).

When I change the field as VARCHAR the table creation is ok.

In the Sequelize documentation : http://docs.sequelizejs.com/manual/tutorial/models-definition.html

Sequelize.UUID
// UUID datatype for PostgreSQL and SQLite
// CHAR(36) BINARY for MySQL

Any idea ?
Regards,

Association and navigation method

Does your mocking module work with association ?
Let's say I have a parent-child model:

var Node = sequelize.define('Node', {
    id: { type: DataTypes.BIGINT, primaryKey: true, autoIncrement: true },
    text: DataTypes.STRING,
  }, {
    classMethods: {
      associate: function (models) {
        Node.hasMany(models.Node, { foreignKey: 'parent', as: 'Children', onDelete: 'CASCADE' });

In my classic model, I have a Node.getChildren() navigation method, when using sequelize-mocking, the same method is undefined.

thanks

Issue mocking with multiple models

Hi! If I have multiple models loaded in my sequelize object, sequelize-mocking appears to only copy one of them (the last one it processes).

sequelize version: 4.4.2
sequelize-mocking version: 1.0.0

Minimal test code which fails for me:

const chai = require('chai');
const sequelizeMockingMocha = require('sequelize-mocking').sequelizeMockingMocha;
const path = require('path');
const Sequelize = require('sequelize');

describe('User class', function () {

    const sequelize = new Sequelize('mysql://user:xyzzy@localhost:3306/');
    const User = sequelize.define('User', {});
    const OtherObject = sequelize.define('OtherObject', {});

    sequelizeMockingMocha(
        sequelize,
        path.resolve(path.join(__dirname, './test.json')),
        {'logging': false}
    );

    it('should exist', function () {
        chai.expect(User).to.exist;
    });
});

test.json file:
[ { "model": "User", "data": { } } ]

Running this test produces the following error for me:

  1. User class "before each" hook for "should exist":
    Error: Model not found: User
    at Loader.loadFixture (node_modules\sequelize-fixtures\lib\loader.js:37:15)
    at . (node_modules\sequelize-fixtures\lib\loader.js:12:21)`

Commenting out the "const OtherObject" line causes the test to pass.

Drilling into the sequelize-mocking code, it appears that the method sequelize-mocking.js#copyCurrentModels doesn't actually manage to copy all the models from the originalSequelize to the mockedSequelize. It iterates over them all, but only the last one processed ends up in the mockedSequelize's ModelManager.

Thanks!

Using this with Tape

Hi,

I write my tests using tape. Would it be straight forward enough to get this module working with it?

locked down sequelize version breaks query generator

Squelize's query generator uses several instanceof checks. Because you are specificfying a specific version of sequelize anyone depending on your library that isnt using that exact version of sequelize is getting broken sql for joins.

This is due to the fact npm will give your library a different sequelize and so when the query builder asks if the association is an instanceof BelongsTo it gets back false becauses its a different BelongsTo.

I recommend adding a ^ to the front of the version specifier so anyone using a 3.X.X will not have this problem.

Unable to mock sequelize transactions

Hi,

I'm unable to mock tests that uses sequelize transactions.

Mocks currently generating START TRANSACTION queries which corresponds to the MySQL syntax.

I already tested using SQLITE as project default database and it correctly generates a query:
BEGIN DEFERRED TRANSACTION

Using following transaction templates:
sql.transaction().then(function (t) { return t.commit(); });

sql.transaction(function (t) { });

Both return the following errors:

Unhandled rejection SequelizeDatabaseError: SQLITE_ERROR: near "START": syntax error
at Query.formatError (./node_modules/sequelize/lib/dialects/sqlite/query.js:424:16)
at afterExecute (./node_modules/sequelize/lib/dialects/sqlite/query.js:120:32)
at replacement (./node_modules/sqlite3/lib/trace.js:19:31)
at Statement.errBack (./node_modules/sqlite3/lib/sqlite3.js:16:21)

Am I doing somthing wrong regarding mocks configuration? Here is my Database Instance
const sql = new Sequelize(config.db.database, config.db.username, config.db.password, { host: config.db.host, dialect: config.db.driver, logging: false, operatorsAliases: Sequelize.Op });

Can't use useHandler or return null.

Hello! I currently have the following, mostly default example, code which produces the error 'TypeError: MockDummyDao.$useHandler is not a function.'

import SequelizeMock from 'sequelize-mock';
const dbMock = new SequelizeMock();

const MockDummyDao = dbMock.define('dummy'); 

MockDummyDao.$useHandler((query) => {
  if(query === 'findById') {
    return null;
  };
});

Ultimately, all I'm trying to do is return a null, just null, not an object. This is what Sequelize actually returns when a record can't be found. This will then consistently test the following code in my service:

const dummyRow: any = await this.dummyDao.findById(2)
  .catch((e) => { console.error(e); });

 if(_.isNull(dummyRow) || _.isUndefined(dummyRow)){
    return null;
  }

return new Dummy(dummyRow.get('message'));

Which behaves as expected live.

Any best way to return null, or insight into why $useHandler doesn't exist would be a huge help! Thanks!

Allow file storage instead of forcing :memory:

Hi,

First of all, thank you for your work. Your lib is great!

It would be nice to allow the use of storage in file.

In my use case I have different connections all along the unit tests. When using the :memory: option, each connection seems to work with it's own allocated memory and so with its own DBs.

I'd like them to share the same DB and the only solution I see here is not to override the storage option.

The concerned code is located in the sequelize-mocking.js file in the adaptSequelizeOptions and a solution would be as follows:

const SQLITE_SEQUELIZE_OPTIONS = {
    'dialect': 'sqlite'
}
const SQLITE_SEQUELIZE_DEFAULT_OPTIONS = {
    'storage': ':memory:'
};

class SequelizeMocking {
    static adaptSequelizeOptions(sequelizeInstance, options) {
        let optionsExtended = _.merge(
            { },
            SQLITE_SEQUELIZE_DEFAULT_OPTIONS,
            sequelizeInstance.options,
            SQLITE_SEQUELIZE_OPTIONS,
            { 'logging': options && !options.logging ? false : console.log }
        );

        return optionsExtended;
    }
    ...
}

I hope I'm clear enough

timestamps being returned as string

I have a timestamp field in my table which I'm trying to mock, however it seems to simply get returned as a string when using sequelize-mocking. It might be an idea to expose transformFixtureDataFn from sequelize-fixtures to do something like the following:

sequelize_fixtures.loadFile('fixtures/users.json', models, {
  transformFixtureDataFn: function (data) {
    if(data.createdAt) {
      data.createdAt = new Date(data.createdAt);
    }
    return data;
  }
})

Allow declare multiple fixture files

Regarding to #21 , it could be insterresting to allow multiple fixtures files

And the sequelize_fixtures module allows it:

   sequelize_fixtures.loadFile('fixtures/test_data.json', models).then(function(){
        doStuffAfterLoad();
    });
 
    //can use glob syntax to select multiple files 
    sequelize_fixtures.loadFile('fixtures/*.json', models).then(function(){
        doStuffAfterLoad();
    });
 
    //array of files 
    sequelize_fixtures.loadFiles(['fixtures/users.json', 'fixtures/data*.json'], models).then(function(){
        doStuffAfterLoad();
    });

So the "fixtureFilePath" could be a string array and so allowed to use the loadFiles method.

Getting error on aftereach restore

I am getting the following error from this library when the tests are done
ER_ROW_IS_REFERENCED: Cannot delete or update a parent row: a foreign key constraint fails

This is obviously because I have foreign keys in my database, so I looked to see how sequelize handles this internally and I found in the query-interface.js on line 238

return self.sequelize.query('PRAGMA foreign_keys = OFF', options).then(function() {
    return dropAllTables(tableNames).then(function() {
        return self.sequelize.query('PRAGMA foreign_keys = ON', options);

So I tried to modify the restore function in your module to do the same

return mockedSequelize
    .query('PRAGMA foreign_keys = OFF', {raw: true})
    .then(function () {
        return mockedSequelize
            .drop({ 'logging': logging })
            .then(function () {
                logging && console.log('SequelizeMocking - Context is restored');
            });
    });

but I still get the same error, so something is not working. Do you have any idea what I am doing wrong?

DataType decimal

When Create model with this type DECIMAL it return js native Number, but sequelize (with postgres) return js type String

Bug occurred about setting a custom timezone is not supported

I use sequelize version 5.19.2. and use mysql.
and set-up like below code.
There is in test file

const Database = require('../../models').sequelize;
    sequelizeMockingMocha(
        Database,
        path.resolve(path.join(__dirname, '../fake-trainer-database.json')),
        {'logging': console.log}
    );

There is in model set-up file

let sequelize;
if (config.use_env_variable) {
  sequelize = new Sequelize(process.env[config.use_env_variable], config);
} else {
  sequelize = new Sequelize(config.database, config.username, config.password, config);
}
...

db.sequelize = sequelize;
db.Sequelize = Sequelize;

db.Trainer = require('./trainer')(sequelize, Sequelize);

I don't know why this error happened.
Are there error in my code?
plz help me.

Error: Setting a custom timezone is not supported by SQLite, dates are always returned as UTC. Please remove the custom timezone parameter.
    at new Sequelize (node_modules/sequelize/lib/sequelize.js:273:13)
    at Function.create (node_modules/sequelize-mocking/lib/sequelize-mocking.js:95:31)
    at createAndLoadFixtureFile (node_modules/sequelize-mocking/lib/sequelize-mocking.js:123:14)
    at wrapper (node_modules/sequelize-mocking/node_modules/lodash/lodash.js:5193:19)
    at Context.<anonymous> (node_modules/sequelize-mocking/lib/sequelize-mocking-mocha.js:33:13)
    at processImmediate (internal/timers.js:439:21)
    at process.topLevelDomainCallback (domain.js:126:23)

TypeError: Cannot read property '__originalSequelize' of null
    at Function.unhookNewModel (node_modules/sequelize-mocking/lib/sequelize-mocking.js:277:29)
    at Function.restore (node_modules/sequelize-mocking/lib/sequelize-mocking.js:249:26)
    at Context.<anonymous> (node_modules/sequelize-mocking/lib/sequelize-mocking-mocha.js:43:18)
    at processImmediate (internal/timers.js:439:21)
    at process.topLevelDomainCallback (domain.js:126:23)

Documentation / Example of how to use?

It's really not clear how to use that module, but since it's maintained, I wonder if there's any chance to get example of how to use? (readme example is not working, due to imports of ../../lib/database, etc)

Thanks

Sequelize.fn not working

Given a model that looks like this:

export default function(sequelize, DataTypes) {
  var User = sequelize.define('User', {
    email: {type: DataTypes.STRING, unique: true},
    password: DataTypes.STRING,
    salt: DataTypes.STRING,
  }, {
    timestamps: false,
    tableName: 'users',
  });

  return User;
}

And a query that looks like this:

import {User, Sequelize} from 'models';

const USER_NOT_FOUND = 'api/server/login/USER_NOT_FOUND';

function login(email, password) {
  return User.findOne({
    where: {
      email,
      password: Sequelize.fn('sha1', Sequelize.fn('concat', password, Sequelize.col('salt'))),
    },
  });
}

export {login, USER_NOT_FOUND};

And a test that looks like this:

  it('returns a user with the correct username and password', done => {
    login('[email protected]', 'password')
      .then(user => expect(user.id).toBe(1))
      .catch(e => console.log(e))
      .finally(done);
  });

I get an error like this:

      Unhandled rejection SequelizeDatabaseError: SQLITE_ERROR: no such column: object Object
          at Query.Object.<anonymous>.Query.formatError (/Users/cameronedwards/Repos/cleanstreamit/node_modules/sequelize-mocking/node_modules/sequelize/lib/dialects/sqlite/query.js:348:14)
          at afterExecute (/Users/cameronedwards/Repos/cleanstreamit/node_modules/sequelize-mocking/node_modules/sequelize/lib/dialects/sqlite/query.js:112:29)
          at replacement (/Users/cameronedwards/Repos/cleanstreamit/node_modules/sequelize-mocking/node_modules/sqlite3/lib/trace.js:20:31)
          at Statement.errBack (/Users/cameronedwards/Repos/cleanstreamit/node_modules/sequelize-mocking/node_modules/sqlite3/lib/sqlite3.js:16:21)

Logged out, the whole error looks like this:

      Error {
        name: 'SequelizeDatabaseError',
        message: 'SQLITE_ERROR: no such column: object Object',
        parent: 
         { Error: SQLITE_ERROR: no such column: object Object
             at Error (native)
           errno: 1,
           code: 'SQLITE_ERROR',
           sql: 'SELECT `id`, `email`, `password`, `salt` FROM `users` AS `User` WHERE `User`.`email` = \'[email protected]\' AND [object Object] LIMIT 1;' },
        original: 
         { Error: SQLITE_ERROR: no such column: object Object
             at Error (native)
           errno: 1,
           code: 'SQLITE_ERROR',
           sql: 'SELECT `id`, `email`, `password`, `salt` FROM `users` AS `User` WHERE `User`.`email` = \'[email protected]\' AND [object Object] LIMIT 1;' },
        sql: 'SELECT `id`, `email`, `password`, `salt` FROM `users` AS `User` WHERE `User`.`email` = \'[email protected]\' AND [object Object] LIMIT 1;' }

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.