Use different file for testing in node js - javascript

I am using a particular set of URLs for connecting to services. They are there in the config.js file. Now while testing using mocha, I want to use a different set of urls. Is it possible to over-ride the urls configured in the js file from the test cases.This is how my config.js looks -
var servercfg = {
host: 'localhost',
port: '9010'
};
var enterprisesercfg = {
userserurl: 'http://localhost:9020',
accountserurl: 'http://localhost:9020',
creditcardserurl: 'http://localhost:9020'
};
var oauth2sercfg = {
url: 'http://localhost:9000/api/oauth2/verify'
};
module.exports={
servercfg,
enterprisesercfg,
oauth2sercfg
};

There are already several solutions to manage your configuration; for example this one: https://github.com/lorenwest/node-config
You define different files for your different NODE_ENV.
//development.json
{
"someURL": "http://url.com"
}
//test.json
{
"someURL: "http://url.com"
}
So all you need to do to change the file from which you load the config is set the NODE_ENV variable when starting your app.
There are other modules besides this one, it's just an example on how to solve your problem.

Related

Requiring files in electron without babel

I'm trying to convert a web application into an electron app. I have multiple functions, in different files that I've imported into my main.js using a transpiler.
However, whenever I try do that in my electron app, I run into an issue with a module I'm using to move away from using php to access my database. Instead I'm using the mysql module on npm.
I want to save this function in its own file, and then require it in main.js. When I try to transpile it with babel, I get an error about Net.Connection not working (or something along those lines). As I understand it, this is because of how Node works. I'm happy to work around this, but I'm hoping there's a way to save this function in another file, and import it without having to use babel.
function loadColourFilter(){
var mysql = require('mysql');
let query_result;
var connection = mysql.createConnection({
host : 'xxxxxxxxxxxx',
user : 'xxxxxxxxxxxx',
password : 'xxxxxxxxxxxx',
database : 'xxxxxxxxxxxx'
});
connection.connect();
let query = "xxxxxxxxxxxxxxxx";
connection.query(query, function (error, results, fields) {
});
connection.end();
return (query_result);
}
EDIT: I've removed some parts of the function to keep credentials safe and whatnot. I'm fairly certain their absence won't change anything when trying to solve this.
EDIT:
My project directory is essentially
src
--- js
--- --- main.js
--- functionFile.js // This would be where my loadColourFilter function above would be saved
--- node_modules
--- --- ...
--- index.html // js/main.js is referenced in a script tag here.
--- main.js // Where the electron window is created.
--- package.json
There should be 2 js contexts, one running in the electron app and one running in node. You won't be able to require you scripts directly from your directory if you are in the electron context (which is like a browser js context).
I'm just assuming this is the case since we don't get a lot of information for your problem, and the other answer should have resolved your problem.
Try to include your js file in your index.html and see what's up.
Edit: Since it's a Transpiling error with babel, babel is probably transpiling for node when it should transpile for the browser.
You can easily make a simple local module using NodeJS by creating a source file and then adding a module.exports assignment to export some functionality/variables/etc from the file. In your case something like a file named colourFilter.js with the contents:
function load(){
var mysql = require('mysql');
let query_result;
var connection = mysql.createConnection({
host : 'xxxxxxxxxxxx',
user : 'xxxxxxxxxxxx',
password : 'xxxxxxxxxxxx',
database : 'xxxxxxxxxxxx'
});
connection.connect();
let query = "xxxxxxxxxxxxxxxx";
connection.query(query, function (error, results, fields) {
});
connection.end();
return (query_result);
}
module.exports = load
And then in your code where you'd like to use it include it by doing something like:
loadColourFilter = require('colourFilter.js')
And use the function like
let result = loadColourFilter()
This is a simple way to split up your code into multiple files/classes/modules but still keep one main file/class/module as the important one which is the public-facing portion or entry point. And of course you don't have to use the names I've used above :P
If you would like to make an object-style module you can instead export an object like
module.exports = {
load
}
Or
module.exports = {
load: loadFunctionNameInThisFile
}
And then use it like
const colourFilter = require('colourFilter.js')
let result = colourFilter.load()

Trouble with Node.js constants

I'm currently learning Node.js and I'm having trouble integrating constants into my service. I have created a constants file and am referencing those values from other files. Unfortunately, I don't seem to be doing it correctly as things start to fail when I reference constants rather than just place literals into all of my function calls.
constants.js
exports.DB_HOST = 'localhost';
exports.DB_PORT = 3306;
exports.DB_USER = 'user';
exports.DB_PASSWORD = 'password';
exports.DB_DATABASE = 'database';
When trying to connect to a MySQL database, the connection fails as the server claims that the credentials are incorrect. However, when I replace all of the constants below with literals, everything works correctly (so I'm not using incorrect authentication information).
var constants = require('constants');
...
var connection = mysql.createConnection({
host: constants.DB_HOST,
port: constants.DB_PORT,
user: constants.DB_USER,
password: constants.DB_PASSWORD,
database: constants.DB_DATABASE
});
...
connection.query('SELECT * FROM table',
function(err, rows, fields) {
res.send(err);
});
constants is a built-in node module that provides system-level constants for use with other built-in modules, like fs, crypto, etc. If you want your constants.js, you will need to include the (absolute or relative) path to it. For example:
var constants = require('./constants');
In addition to changing your require() to use your local module rather than a built-in module:
var constants = require('./constants');
There is a misspelling here in your code:
port: constants.DB_POST,
// wrong character ^
should be:
port: constants.DB_PORT,
So, a couple things:
It looks like you're trying to require either an installed node module called constants or a built-in module (which is pretty much a set of constants for us in built-in node modules like fs, http, crypto, etc.). That would be the main reason you can't access it. Node doesn't know to look for your local module b/c no path string has been supplied.
you might be able to clean up your module a bit w/ some optional but (sometimes) helpful refactoring.
I would recommend the following change to how you require your module:
// Bc it's a set of constants, use the es6/2015 `const` if available when requiring your module
const constants = require('./constants');
You could clean up your module a little bit w/ module.exports; makes it really clear what the object you're exposing is:
module.exports = {
DB_HOST : 'localhost',
DB_PORT : 3306,
DB_USER : 'user',
DB_PASSWORD : 'password',
DB_DATABASE : 'database',
}
Another consideration: in most apps, you really want to keep configuration as internally-stateless as possible. That means your app shouldn't really have any configurational values hard-coded into it. Generally, if you avoid doing so you will have a much more flexible setup externally. In other words, you'd be able to spin up as many different instances as you want with as many different databases to connect to. When you change databases, you'd only have to change the environment, not the app itself. And, if you get into the semantics of it all, your app's job is to connect, not to really decide where to connect — the environment should provide that. So, these could be made available from your module as:
const config = {
DB_HOST : process.env.DB_HOST,
DB_PORT : process.env.DB_PORT,
DB_USER : process.env.DB_USER,
DB_PASSWORD : process.env.DB_PASSWORD,
DB_DATABASE : process.env.DB_DATABASE,
};
module.exports = config;
You could just access them from anywhere with process.env.YOUR_VAR, but if you want to consolidate them all in a module that is just as good in many ways and would let you change external config value variable names (i.e. process.env.DB_USERNAME instead of DB_USER) and not have to change it everywhere else (if you don't need the names to be kept in sync).
Hope that helps! :)

Best way to load modules node.js

My project has got many folders and I often load my own modules in node.js in the following way:
var request = require("request"),
config = require("../../../modules/config"),
urls = require("../../../modules/urls");
I sometimes move the folders around and the path changes, so I need to adjust the ../ part manually.
I don't want to move my modules into the node_modules folder, but I'd like to load the modules in the following way:
var request = require("request"),
config = require("config"),
urls = require("urls");
or
var request = require("request"),
config = require("modules/config"),
urls = require("modules/urls");
What are my options?
New Answer:
Relative paths seem to be the simplest choice after all, it allows you to run your script from any location.
var config = require("../../config");
Old answer:
I found out that, while not ideal, there's also the possibility to use process.cwd().
var request = require("request"),
config = require(process.cwd() + "/modules/config");
or, if the process.cwd() is set to a global variable in the main js file
global.cwd = process.cwd();
then
var request = require("request"),
config = require(global.cwd + "/modules/config"),
urls = require(global.cwd + "/modules/urls");
You can try to do the following, based on some conditions
if the scripts are exclusively written for your application, meaning it won't work with any other application, and the scripts don't have any dependencies place them under modules directory and try to create expose a variable such as global.basepath and using path.join to construct the filepath and require it.You could also inject module variable after you require them at the main script of your app.
main.js
var config = require('modules/config.js')(_,mongoose,app);
modules/config.js
module.exports=function(_,mongoose,app){
return function(){
// _,mongoose,app
this.loadConfigVariable..
}
}
if the scripts are not one-files that have separate tests, require other vendor modules in order to be executed then create individual node modules and publish them to a registry for convenience when installing the main application.
Just as express does, there is the main application express and there are modules that express uses such as express-validation which in turn has its own dependencies.
You could add a symlink in node_modules, pointing to wherever your modules are.
For example, add a symlink named "my_modules", referencing '../foo/bar/my_modules'. Then, your requires will look like
var config = require('my_modules/config');
var urls = require('my_modules/urls');

SailsJS custom config files

I am aware I can create a custom file inside the config directory and reference the variables from within that
module.exports.myconfig = {
foo: 'bar'
}
sails.config.myconfig.foo
But I need to write to these variables too and have them saved. In previous projects I have done this with JSON config files and used PHP to write to them.
Is there any way of doing this with Sails or should I just create some JSON files to pull and push my config vars?
There's no mechanism built in to Sails for persisting configuration variables. However, in the latest build of Sails there is a lower event you can listen for which indicates that Sails is exiting. You could catch this and persist your data then. For example, in your /config/bootstrap.js, something like:
var fs = require('fs');
module.exports = function(cb) {
sails.on('lower', function persistConfig() {
fs.writeFileSync(sails.appPath+'/config/myConfig.js',
'module.exports = ' + JSON.stringify(sails.config.myconfig));
});
// ... other bootstrap stuff ...
return cb();
}

Is there a Java classpath-like feature for server-side Javascript?

When using JUnit and Maven in Java, one can have separate property files for src/main and src/test. This allows different configuration for code and tests, having Maven to manage the resources by using Java classpath.
Is there a similar way in Javascript code run by Node.js? I use Mocha for unit-testing and Grunt for task management.
Code example for script.js:
var config = require('./config/dev/app.js');
exports.getFileName = function() {
return config.fileName; // returns 'code.txt'
}
What I need is to make the script.js use different config file when being required in a test.js unit test like this:
var assert = require('assert');
var s = require('./script.js');
describe('Test', function () {
it('should use different config file', function() {
assert.equal('test.txt', s.getFileName());
});
});
Is there a way to use different configuration ./config/test/app.js in the script.js without having to alter the code of script.js? What I really try to avoid is to adjust the code to support unit tests. Instead, I want to achieve similar functionality such as mentioned Java classpath.
Please try this code.
Script.js
var config;
if(process.env.dev===true){
config = require('./config/dev/config.js');
}
if(process.env.prod===true){
config = require('./config/prod/config.js');
}
exports.getFileName = function() {
return config.fileName; // returns 'code.txt'
}
test.js
//set the environment here
process.env.dev = true;
var assert = require('assert');
var s = require('./script.js');
describe('Test', function () {
it('should use different config file', function() {
assert.equal('test.txt', s.getFileName());
});
});
I have not found any elegant solution out there on the web so I have implemented and published my own.
Check it out here: https://npmjs.org/package/app-config
Using the app-config plugin, only the script.js needs to get changed this way:
var config = require('app-config').app;
exports.getFileName = function() {
return config.fileName; // returns 'code.txt'
}
The app needs to be run this way for example
NODE_ENV=dev node script.js
NODE_ENV=unitTest mocha test.js
Depending on the NODE_ENV environmental variable, the right set of configuration files will be loaded by the app-config plugin.

Categories

Resources