DEV Community

loading...

ReScript and Jest’s manual mocks

John Jackson
I’m probably riding my bicycle or coding.
Updated on ・2 min read

This article was originally written with ReasonML. I updated it in May 2021 to use ReScript.

While developing tests for Coronate, I needed mock data to simulate real-world usage. However, almost every page of the app relies on loading and saving data from an async database. To simplify tests, I needed to simulate the database with synchronous data instead.

The Jest feature we’re looking for is manual mocks. Let’s say you have a module called Db which connects to a database and retrieves data. With Jest, you can create a directory next to your module called __mocks__ and then put a mock version of your module in there. Jest will use that instead of your real one. (There are actually a few more steps involved, which the docs explain in detail.)

With ReScript code, there is a catch. Every module must have a unique name, so two Db.re files is illegal. And, unlike JavaScript, ReScript ignores directory structure and treats every file like it’s a top-level module.

Fortunately, the workaround isn’t difficult. We simply have to find a way play by Jest’s and by ReScript’s rules at the same time.

First, create your __mocks__ directory like you normally would. Then, instead of creating Db.re, create Db_Mock.re inside that folder. When this compiles to Db_Mock.bs.js, Jest won’t be able to detect it, since Jest is looking for Db.bs.js. To fix that, manually create a Db.bs.js inside __mocks__ and add the following line to it:

export * from "./Db_Mock.bs";
Enter fullscreen mode Exit fullscreen mode

Jest will now load your mock version of Db, which will in turn load Db_Mock.

A few notes:

  • This works best when your in-source is set to true in bsconfig.json.
  • If you’re not committing your *.bs.js to your version control, then make sure you make an exception to commit the ones in your mocks folder.
  • This will mean all of your mocked functions are not being tested. Make sure you test those separately!

Discussion (0)