How I finally been able to mock Sequelize with NodeJS using Mocha, Chai, Sinon & Sequelize-mock?

How I finally been able to mock Sequelize with NodeJS using Mocha, Chai, Sinon & Sequelize-mock?

Unit Testing

Unit testing is important for developing reliable applications. For me, the best benefit is when you modify codes either to remove bugs or to add new features, you already know if something is broken. Obviously doing integration tests is more useful than unit tests as the later abstracts and mocks a lot of things while the former is closer to real world conditions. But one thing you can be sure of, especially with language that are not strong typed such as JavaScript and Python; you know which method signature or expected value has changed.

For me, if an organisation is serious about developing real world applications, Unit Testing is a must, unless you jump directly to Integration Testing. An example in the JavaScript world is the library Supertest. The setting up takes more time and is more challenging as you need a lot of configuration. That's why for a beginning, Unit Testing is good enough.

Sequelize

Sequelize

When I begin working at my current company, I am tasked with writing unit tests for existing applications. The process is straightforward but I struggle mocking Sequelize, the database Object Relation Mapper (ORM) library. After countless of hours of experimentation, I revert back to Integration Testing. This is nevertheless way more complicated to setup - especially for an ongoing project compared to a new one - with the sheer amount of files and codes to be covered. For instance, I need to setup a separate database and configuration file because the codes will run on a real database and write real files on the server. This can be challenging to do, especially when determining which database and configuration to use when launching the tests and the housekeeping afterwards. All of that workflow definitely takes far more time than setting up unit tests. That's why the best practice is to first start with them.

The integration testing process is simple though: use a testing database and configuration, and go through each API, build data in the database and test for expected outcomes. The biggest disadvantage, nonetheless, is the sheer amount of time the whole test suite took, usually around five to ten minutes for approximately 60 tests. I usually run only one test a time but once done, to see if there is a regression, I again need to run the entire tests. The process sometimes takes hours only for me to write a few successful tests with enough code coverage. In my experience, the interaction with the database takes the most time.

Fruitful - Free WordPress Responsive theme source code displayed on this photo, you can download it for free on wordpress.org or purchase PRO version here https://goo.gl/hYGXcj
Photo by Ilya Pavlov / Unsplash

Jest and Sequelize

A few months later, I begin working on another project built with TypeScript using Jest as testing library. This time, mocking out the Sequelize ORM and the built-in functions such as findOne to return a custom value is much easier. Writing unit tests to mock out dependencies is therefore more efficient.

CoffeeScript and Jest

Now back to CoffeeScript on another project - I try using Jest - which does not play well with the scripting language. The setups seems to be challenging and time consuming even with the use a plugin called jest-preset-coffeescript.

As time is scarce with looming deadlines, I don't have the luxury of experimenting with all the possibilities. Another useful plugin is babel-preset-jest but we don't use babel configuration for this project.

I therefore crawl back to the stack that I have the most experience with: Mocha, Chai and Sinon. Mocha is the test runner similar to Karma, Chai is an assertion library and sinon for spies, fakes, stubbing or mocking objects.

StackShare

For mocking Sequelize, I've try plenty of solutions, including:

Although most of the solutions do not work (or I don't know how to), my aim is to learn most about this aspect of unit testing in this limited time. Some of them are highly inefficient, requiring a lot of work only for the setup while others simply do not get along with the existing frameworks.

I also try other libraries for object and dependency mocking for Sequelize such as:

  • mock-require
  • proxyquire
  • mockery

For the sole goal of mocking a Sequelize function such as Model.findOne to return a determined value, the setup is cumbersome. I therefore return to Sinon which is straightforward for spying, stubbing and mocking objects. Nevertheless, this doesn't work even when I try changing the prototype value; for example, User.prototype.save.

With Jest, you can simply write jest.spyOn(User.prototype, 'findOne').mockResolvedValueOnce([]) to return the value you want.

With additional reading on the subject on StackOverflow, Github and technical blogs, I try sequelize-mock once again, putting into practice whatever I've learnt and experimenting a lot with one library at a time. The result pays off. With only a few lines without additional setup, the Sequelize ORM models can be mocked out. Here is an example from the npm site:

https://www.npmjs.com/package/sequelize-mock


If my articles help you and you want to support my work, you can buy me a coffee: