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.
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.
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:
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:
If my articles help you and you want to support my work, you can buy me a coffee: