How do I override config values at runtime with node-config?

jcollum picture jcollum · Sep 22, 2017 · Viewed 8.2k times · Source

I'd like to override some values at test-time, specifically setting my retries for an http service to 1 (immediate failure, no retries). Our project uses node-config. According to the docs I can override with NODE_CONFIG env variable:

node myapp.js --NODE_CONFIG='{"Customer":{"dbConfig":{"host":"customerdb.prod"}}}'

Well I would prefer to do this in my test, but not for all tests. The code says that you can allow config mutations by setting ALLOW_CONFIG_MUTATIONS.

process.env.ALLOW_CONFIG_MUTATIONS = "true";
const importFresh = require('import-fresh');
importFresh("config");

process.env.NODE_CONFIG = JSON.stringify({httpServices:{integration:{enrich: {retryInterval: 1, retries: 1}}}});
expect(process.env.NODE_CONFIG, 'NODE_CONFIG not set').to.exist();
expect(process.env.NODE_CONFIG, 'NODE_CONFIG not set').to.match(/retryInterval/);
expect(process.env.ALLOW_CONFIG_MUTATIONS, 'ALLOW_CONFIG_MUTATIONS not set').to.equal("true");

const testConfig = require("config");
console.dir(testConfig.get("httpServices.integration.enrich"));
expect(testConfig.get("httpServices.integration.enrich.retryInterval"), 'config value not set to 1').to.equal(1);

Result:

{ url: 'https://internal-**********',
  retryInterval: 5000,
  retries: 5 }
 `Error: config value not set to 1: Expected 5000 to equal specified value: 1`

How do I get this override to work?

(expect is from Hapi.js Code library)

Answer

Mark Stosberg picture Mark Stosberg · Sep 22, 2017

I'm one of the maintainers of node-config. Your bug is that you used require the second time when you should have used importFresh again.

Your first use of "importFresh()" does nothing different than require() would, because it is the first use of require().

After setting some variables, you call require(), which will return the copy of config already generated and cached, ignoring the effects of the environment variables set.

You only needed to use importFresh() once, where you currently use require(). This will cause a "fresh" copy of the config object to be returned, as you expected.