Unit testing and mocking fs.ReadFileSync
May 28, 2020 - 3 mins read time - 502 words - garrardkitchen
I’d just ran npm run test
in a newly created package I’d added to a monorepo (lerna) I’d created for a project I was working on that integrates with Twilio Sync, RabbitMQ, Twilio TaskRouter and MSSQL, and I go this:
*******************************consumers\packages\eda [CRMBROK-233 +0 ~2 -0 !]> npm run test
> @cf247/eda@1.0.2 test *******************************consumers\packages\eda
> jest
FAIL __tests__/eda.test.js
● Test suite failed to run
ENOENT: no such file or directory, open '.env'
2 | const fs = require('fs')
3 | const dotenv = require('dotenv')
> 4 | const envConfig = dotenv.parse(fs.readFileSync(`.env`))
| ^
5 | for (const k in envConfig) {
6 | process.env[k] = envConfig[k]
7 | }
at Object.<anonymous> (lib/setenv.js:4:35)
at Object.<anonymous> (lib/eda.js:1:1)
Test Suites: 1 failed, 1 total
Tests: 0 total
Snapshots: 0 total
Time: 1.772 s
Ran all test suites.
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! @cf247/eda@1.0.2 test: `jest`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the @cf247/eda@1.0.2 test script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm WARN Local package.json exists, but node_modules missing, did you mean to install?
npm ERR! A complete log of this run can be found in:
npm ERR! *******************************\npm-cache\_logs\2020-05-28T08_04_32_271Z-debug.log
*******************************consumers\packages\eda [CRMBROK-233 +0 ~3 -0 !]>
Not great but hey, first run and all!
The error message tells me everything I need to know:
ENOENT: no such file or directory, open '.env'
2 | const fs = require('fs')
3 | const dotenv = require('dotenv')
> 4 | const envConfig = dotenv.parse(fs.readFileSync(`.env`))
Which is that it can’t find an .env
file. And it wouldn’t. Later refactoring would remove this file dependency but for now, all I want to do is to get my test working.
This was the unit test code:
'use strict'
const eda = require('..')
describe('@cf247/eda', () => {
it('no tests', () => {
})
})
This is the code from the module it was importing via the require('..')
statement:
require('./setenv')
const amqp = require('amqplib/callback_api');
module.exports = (io, emitter) => {
...
The top line is importing code from this file:
I’ve highlighted the problematic line of code
|
|
The quickest (IMO) way to deal with this and move forward is to Mock the fs
class. I did this by included a jest module mock into my unit test file:
I’ve highlighted the mock related code
|
|
What this does is, when the readFileSync
class function is called, it always returns an empty array []
. As the unit code does not have a dependency on environment variables, this mocked response will work fine.