Search code examples
node.jsmongodbunit-testingjestjsin-memory-database

Jest: global setup async with access to jest for mocking purposes


Scenario Running Jest to unit-test a nodejs API running a in-memory instance of mongodb (via mongodb-memory-server)

My goal The in-memory db should start only once for ALL the test files.

Why While firing up 1 database PER FILE is not even a big deal (as long at is runs fast) the most important reason is that the plugin at first fetches the mongo binaries via an heavy download (if they are not already in the cache). So it makes sense to do this operation only once instead of ONCE PER FILE because the download acts in the exact same way (it takes files form the web and places them into a folder).

The problem Beside firing up the in-memory mongo I need also to mock my dbService.js file so that every file depending on it will use the mocked version (and thus the in-memory server). So I cannot really use the globalSetup option of Jest because in that file jest is undefined. I cannot even use setupFiles because they run PER FILE and they are synchronous while by nature of mongodb connect I need an async function. I tried also using beforeAll in every file passing a common utility module but since the tests files run in parallel even the utility module is run one time per file.

Also I would like to avoid to have 1 unique test file. I get that is a workaround but I was wondering if there is a simple and clean solution. The perfect scenario is "Do something first asynch, then do the tests in parallel". Shouldn't be that hard no?


Solution

  • What I would do is download the file in globalSetup, and then set up your db and mock mock either in the __mocks__ directory or in setupFiles to avoid having to set it up explicitly in every test.

    The __mocks__ directory is preferable as the mock is then only run when your code ends up requiring that file instead of in every single test.