Skip to main content
Version: 12.x (Current)

Development Affordance

To aid you in the development and testing of your service locally on your machine we provide some affordances that you can use.

ENV Variables for Local Runs

If you need to use some ENV variables inside your service to customize its behavior you can use the --env flag and pass a .env file path to it.
For example you can add this script to your package.json:

"scripts": {
"start": "lc39 index.js",
"start:local": "npm start -- --env-path ./local.env",
},

And then you will run the following command for starting the server locally:

npm run start:local

ENV Variables for Testing

In a similar way, if your service needs to work with ENV variable we have some tips that will set you up for using them in a safe way both in runtime and during unit testing your web service.

Safe Use of ENV Variables During Runtime

We will reccommend to use the fastify-env package for validating them against a JSON schema that you control.
Inside your main entry point for the service you then can do somenthing like that:

const fastifyEnv = require('fastify-env')

const envSchema = { ... }

module.exports = async function service(fastify) {
fastify.register(fastifyEnv, { schema: envSchema })
}

In this way you can access all your ENV variables with fastify.config, and if one of them do not conform to your schema the service will crash.

Safe Use of ENV Variables During Runtime

For your tests if you have followed the previous advice you can add i tiny bit to it for a very big gain:

const fastifyEnv = require('fastify-env')

const envSchema = { ... }

module.exports = async function service(fastify, options) {
fastify.register(fastifyEnv, { schema: envSchema, data: options })
fastify.register(fastifyEnv)
}

As you can see, the only difference is that we pass the options object as the base data for fastify-env. In doing so, we will merge it with the ENV variables loaded in runtime giving the former precedence over the latter.
Running the service normally will not change anything, because the options object will not be populated, but you can use it during your tests for changing them very easily:

const lc39 = require('@mia-platform/lc39')
const test = require('tap').test

test('A simple test', async assert => {
const options {
envVariables: {
ENV_VARIABLE: 'value',
}
}
const fastify = await lc39('./path/to/entrypoint/from/root', options)
...
})

From the fastify variable returned you can then customized it for your tests and injecting the calls you need to tests.
By default the started instance is not listening on any port and will start the logger at the silent level.
If you need to see the log you can set the logLevel key inside the options object and you are free to bind the fastify instance on any address and port using its available methods.

Capture the Log Stream

In some cases during the tests you want to capture the logs emitted from the logger and do assertions on them. For this cases you can set the stream key that accept a writable stream. Once written the data is at your disposal, the simplest stream you can use is the PassThrough stream of node:

const { PassThrough } = require('stream')
const lc39 = require('@mia-platform/lc39')
const test = require('tap').test
test('A simple test', async assert => {
const stream = new PassThrough()
const options {
logLevel: 'info',
stream,
}

const fastify = await lc39('./path/to/entrypoint/from/root', options)
const log = stream.read().toString()
...
})