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";
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 totrue
inbsconfig.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!
Top comments (0)