Grab Bag - Sequelize, Jest, and JSON Validation
November 21, 2021
I’ve been working on a project from a different computer, and have been taking notes for this blog as I go. Forgot to add them though! Here is a grab bag of topics from the past couple of months.
Using the New Sequelize CLI
In the new project I’m using the latest version of sequelize-cli
for the first time. Not surprisingly, some updates have been made to keep up with the changes that were made for the latest version of sequelize
.
A notable difference is that the cli now prefers extending the Model
class instead of using sequelize.define
to generate a new model. The syntax isn’t too different, but it’s hardly documented at all. I found this issue which discusses the new syntax and contains an example showing how to include associations. There are other examples showing ways to include getters and setters which may be useful in the future. Let’s not talk about the fact that these examples are 5 years old and still not documented…
A Case For Not Using Sequelize ORM
Every time I start a new project I go through the labor of “is this the best way to do X” where “this” is whatever I did on a previous project. I often come to the conclusion of no—there is probably a better way to do X—but then I do X anyway because I know I can do it faster 😆
Well this time, “this” was using Sequelize as ORM to handle all my database code. I do want to get more practice with raw SQL to develop that skill, but in the interest of time I went with old faithful for this project.
Not so faithful! There have been a lot of breaking changes since I last used sequelize and I keep running into changes that haven’t been documented. One tiny change is the use of the underscored
option on a model.
You used to be able to add underscored: true
to a model definition, and it would ensure all table names and column names are underscored instead of camel case (i.e. created_at
instead of createdAt
). For a not very strong reason, I prefer this.
In the new version, underscored
seems to have been combined with another option underscoredAll
(never heard of it, but that’s beside the point!), and the behavior totally changed. A lot of people have run into the same issue and the most useful explanation seems never to have made it into any documentation.
This small change had some weird side effects:
- Database table name was uncapitalized (
users
instead ofUsers
) - Model instances were created with both a
created_at
andCreatedAt
field - Model instance wouldn’t get created at all if
allowNull
was set tofalse
on the underscored fields, even with adefaultValue
set
In the end I just decided to use the default camelCase column names to not have to figure this out, but it was a really annoying 30 minutes or so looking into where the issues were coming from.
Is that enough of a reason not to use ORMs to interact with a database. It definitely adds to the case against Sequelize at least, since the documentation makes a huge difference.
Testing App Controllers with Jest
I want to include tests with this app and do it properly. It would be much better than manually testing each route as I have been doing, and probably more of a fail safe. I’ve found a lot of resources to try and learn how to do this:
- Jest Crash Course video which includes mocks
- Community question: How can I test rest api using express and only JEST?
- StackOverflow question How to write a unit test an Express controller using Jest? with code examples
- StackOverflow question How to unit test controllers in node.js applications? with code examples using Sinon
- Testing Routes and Controllers on The Odin Project — uses the Supertest library and creates a new
app()
instance to run the tests. - Unit Testing Expressjs Controller article — uses Mocha, Istanbul, and Sinon…looks promising.
Validating JSON
I ran into an issue where I was copying some text from a PowerPoint deck into a JSON object. I kept getting Unexpected token in JSON at position X
errors, where X
was a pretty high number like 247 or 468. I have no desire to count characters in this text! My quick but painful solution was to re-type all of the text, and the error went away.
Then I came across this JSON validator tool and found a much better solution for this! I copy/pasted the offending text into the validator and sure enough, there were two whitespace characters in the text, wreaking havoc. Now I know for next time.