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
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_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
__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
A few notes:
- This works best when your
in-sourceis set to
- If you’re not committing your
*.bs.jsto 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!