"x" is not a constructor - javascript

I'm trying to get a result from Sql query.
I have the following class which should execute the Sql connection and query:
'use strict';
//db.js
const sql = require('mssql');
require('dotenv').config();
var utils = function(){
var config = {
server: 'sql01',
database: 'db123',
options: {
instanceName: 'in1',
encrypt: true
}
};
module.exports = {
/** Define sql queries here */
GetEmpName(id) {
let my_query = `Select filed1 FROM db123 WHERE id='${id}'`;
sql.connect(config).then(function () {
new sql.Request()
.query(my_query).then(function (recordset) {}).catch(function (err) {
console.log(err);
});
});
}
};
};
And that's the main page:
'use strict;'
let HomePage = require('../page/home_page.js');
let utilsPage = require('../utils/utils.js');
describe("login to website",function(){
let employeeId;
let employeeBday;
let home = new HomePage();
//let utils = new utilsPage();
it('get an employee's Id', function (done) {
utilsPage.GetEmpName('100001387');
done();
})
});
I'm getting an error says: utilsPage is not a constructor.
What am I doing wrong?

In Node.js there are two ways of exporting and accessing function variables. One is by creating a global function and putting all your functions, variables into that and export that module as a whole by using module.exports.
Another way is just exporting the function by exports and then accessing that in your specific file. So in your case you could do it in either of the below 2 ways-
1st Approach: Using your Utils function globally -
'use strict';
//db.js
const sql = require('mssql');
require('dotenv').config();
var utils = function(){
this.config = {
server: 'sql01',
database: 'db123',
options: {
instanceName: 'in1',
encrypt: true
}
};
/** Define sql queries here */
this.getEmpName = function(id) {
let my_query = `Select filed1 FROM db123 WHERE id='${id}'`;
sql.connect(config).then(function () {
new sql.Request()
.query(my_query).then(function (recordset) {}).catch(function (err) {
console.log(err);
});
});
}
};
module.exports = new utils();
You could use it the same way as you have used -
'use strict;'
let HomePage = require('../page/home_page.js');
let utilsPage = require('../utils/utils.js');
describe("login to website",function(){
let employeeId;
let employeeBday;
let home = new HomePage();
it('get an employee's Id', function (done) {
utilsPage.getEmpName('100001387');
done();
})
});
2nd Approach: Exporting only the getEmpName function -
'use strict';
//db.js
const sql = require('mssql');
require('dotenv').config();
var config = {
server: 'sql01',
database: 'db123',
options: {
instanceName: 'in1',
encrypt: true
}
};
/** Define sql queries here */
exports.getEmpName = function(id) {
let my_query = `Select filed1 FROM db123 WHERE id='${id}'`;
sql.connect(config).then(function () {
new sql.Request()
.query(my_query).then(function (recordset) {}).catch(function (err) {
console.log(err);
});
});
}
You would use it the same as well:
'use strict;'
let HomePage = require('../page/home_page.js');
let utilsPage = require('../utils/utils.js');
describe("login to website",function(){
let employeeId;
let employeeBday;
let home = new HomePage();
it('get an employee's Id', function (done) {
utilsPage.getEmpName('100001387');
done();
})

In your utils.js file you shouldn't wrap your code in the utils function
'use strict';
//db.js
const sql = require('mssql');
require('dotenv').config();
var config = {
server: 'sql01',
database: 'db123',
options: {
instanceName: 'in1',
encrypt: true
}
};
module.exports = {
/** Define sql queries here */
GetEmpName(id) {
let my_query = `Select filed1 FROM db123 WHERE id='${id}'`;
sql.connect(config).then(function () {
new sql.Request()
.query(my_query).then(function (recordset) { }).catch(function (err) {
console.log(err);
});
});
}
};
In your main page file you can access your exported module like this
utilsPage.GetEmpName('100001387')
There's no need to call new utilsPage(). In order to use the keyword new you must either export a class or a constructor function.

Related

mock dynamodb partiql using jest

I didn't find a way to mock the new feature of dynamodb "PartiQL" defined in a lambda function.
In PartiQL we can use executeStatement to run sql like queries which are a kind of DynamoDBCustomizations.
But he configuration below return an error:
UnrecognizedClientException: The security token included in the
request is invalid
which means that the configuration of jest-mock is not correct.
This is the code to be tested
'use strict';
var ddb = new AWS.DynamoDB({ apiVersion: '2012-08-10' });
const TABLE_NAME = process.env.TABLE_NAME;
async function queryTest() {
let params = {
Statement: `select * from ${TABLE_NAME}`
};
let statementResult = await ddb.executeStatement(params).promise();
return statementResult.Items;
}
module.exports.get = async (event) => {
var result = queryTest();
if (!result) {
return {
statusCode: 200,
body: JSON.stringify(result)
};
}
else {
return {
statusCode: 400,
body: JSON.stringify(result)
};
}
};
and the testing script:
'use strict';
const AWS = require('aws-sdk');
const jestPlugin = require('serverless-jest-plugin');
const lambdaWrapper = jestPlugin.lambdaWrapper;
const mod = require('./handler');
function mock_aws() {
let mockDynamoDBClient = {
executeStatement: {
promise: jest.fn()
},
promise: jest.fn(),
};
jest.mock("aws-sdk", () => {
const config = {
update: jest.fn(),
};
return {
DynamoDB: jest.fn().mockImplementation(() => {
return {
executeStatement: () => mockDynamoDBClient.executeStatement,
};
}),
config: config
};
});
return mockDynamoDBClient;
}
describe('test', () => {
const OLD_ENV = process.env;
var mDynamoDb;
var wrapped;
beforeAll(async () => {
jest.resetModules();
wrapped = await lambdaWrapper.wrap(mod, { handler: 'get' });
process.env = { ...OLD_ENV };
process.env.TABLE_NAME = "TEST";
mDynamoDb = mock_aws();
});
test('implement tests here', async (done) => {
const mResult = [{ 'TEST': 1 }] ;
const response = await wrapped.run({})
expect(response).toEqual({
"statusCode": 200,
"body": JSON.stringify(mResult)
});
done();
});
});

Reusing SQL server Database Connections With Azure Functions Using Javascript

I cannot find clear information on how to manage SQL server database connections from an Azure function written in Javascript.
I am using a connection pool code -
const pool = new sql.ConnectionPool(config);
const poolConnect = pool.connect();
pool.on('error', err => {
// ... error handler
})
and I am using the poolConnect object from the function which is executing the query
export const selectQuery = function() {
const connectionPool = await mssqlDBPoolConnect;
const request = connectionPool.request();
await request.query('select query');
}
So how can I use the same connection pool across all azure functions.
Create two folder named config and toolkit under your root path. Put your db.js in config folder, and create a sql helper class to export a function named sqltools.js in toolkit folder.
So you could use the same connection pool by calling sqltools in your function's code. This step help you to reduce using the same code in every function.
Try use the db.js code below:
const sql = require('mssql')
const config = {
user: 'yourusername',
password: 'yourpassword',
server: 'yoursqlserver.database.windows.net', // You can use 'localhost\\instance' to connect to named instance. Do not use TCP.
database: 'yourdb',
"options": {
"encrypt": true,
"enableArithAbort": true
}
}
const poolPromise = new sql.ConnectionPool(config)
.connect()
.then(pool => {
console.log('Connected to MSSQL')
return pool
})
.catch(err => console.log('Database Connection Failed! Bad Config: ', err))
module.exports = {
sql, poolPromise
}
The sqltools.js class:
const { poolPromise } = require('../config/db')
module.exports.sqltools = {
ExecSqlQuery : async function(arg){
const pool = await poolPromise
//SELECT *FROM SYSOBJECTS WHERE xtype = \'U\'
var result=null;
try {
result = await pool.request()
.query(arg)
} catch (error) {
console.log(error.message);
}
return result;
},
ExecProce : function (arg2, arg3, arg4){
console.log(arg2,arg3,arg4);
}
}
Here is my HttpTrigger1 index.js code, call ExecSqlQuery to exec sqlstrings:
const { sqltools } = require('../toolkit/sqltools');
module.exports = async function (context, req) {
context.log('JavaScript HTTP trigger function processed a request.');
var result=null;
try {
// call ExecSqlQuery func
result = await sqltools.ExecSqlQuery('SELECT *FROM SYSOBJECTS WHERE xtype = \'U\'');
} catch (error) {
console.log(error.message);
}
const responseMessage ="Func 1 Result : TableName= " + result.recordset[0].name;
context.res = {
// status: 200, /* Defaults to 200 */
body: responseMessage
};
}

Why does a unit test with sinon createStubInstance is successful but hangs?

I'm unit testing a method in fileA.js that requires a new class instance from fileB.js with success.
The problem is that I get success, as expected but this specific test hangs and I don't get results from istanbul.
Yes, I have already added --exit flag. This only happens if I run this test... Why does it hang?
This is the method in fileA.js:
global.mapperObj = {};
const opts = config.opts
(...)
async function startServices() {
const data = await getData();
Object.keys(data).forEach(function(key) {
mapperObj[key] = new ClassInFileB(key, data[key], opts);
mapperArray.push(key);
});
}
The class in fileB.js:
const npmPool = require('npmPackage');
class ClassInFileB{
constructor(ip, port, opts) {
this.classPool = npmPool.createPool(ip, port, opts);
}
(...)
// other class methods
}
And the test for that method:
const rewire = require('rewire');
const fileA = rewire(`path/to/fileA`);
const ClassInFileB = require(`path/to/fileB`);
describe('Testing startServices() function', function () {
it('It should not throw errors', async function () {
let result;
let error = false;
global.mapperArray = [];
try {
function getDataMock() {
return { '0.0.0.1': 'thisIsSomething'};
}
fileA.__set__('getData', getDataMock);
// Create a stub instance to ClassInFileB class avoiding the constructor
sinon.createStubInstance(ClassInFileB);
result = await fileA.startServices();
} catch (err) {
error = err;
}
expect(error).to.be.false;
});

How can i write a mocha/chai test for a database connection along with queries?

I'm trying to test the dbMysqlConnect function in the file I that's being tested, but I'm having trouble actually testing the function for I always get an error when trying to establish a connection. How would you go about writing a test for a situation like this? Any help would be appreciated.
Error in console window:
Error: connect ECONNREFUSED 127.0.0.1:3306
Test File:
const mysql = require('mysql');
const mssql = require('mssql');
const actions = require('../src/actions');
const knowledgePortalAPI = require ('../src/api/knowledgePortalAPI');
const rewire = require('rewire');
const { expect } = require('chai');
const MockAdapter = require('axios-mock-adapter');
const Store = require('./store');
//import the updatedState and Event Variables from the store.
const newStore = new Store();
let updatedState = newStore.getUpdatedState();
let event = newStore.getEvent();
let initialState = newStore.getInitialState();
const _ = require('lodash');
describe('testing actions.js file', () => {
it('testing dbMysqlConnect function', async () => {
updatedState = _.cloneDeep(initialState);
const router = rewire('../src/actions');
const dbMysqlConnect = router.__get__('dbMysqlConnect');
let memoObject = await dbMysqlConnect(updatedState, event);
});
});
actions.js:
const mysql = require('mysql');
const mssql = require('mssql');
const axios = require('axios');
const AD = require('ad');
const bp = require('botpress');
const configMS = require('./configMS');
const configMY = require('./configMY');
const Querystring = require('querystring');
const flatten = require('flat');
const moment = require('moment');
const { viewClaimSummary, viewClaimLineDetail, viewClaimSummaryMulti, providerDemographics, claimConsolidated, memoService } = require('./api');
const realTimeFlowDialogEngine = require('./RealTimeFlowDialogEngine/documentDialogEngine');
const claimsDocumentAutoRoutingEngine = require('./RealTimeFlowDialogEngine/claimsSOPDocumentRouter');
const messageStressTest = require('./RealTimeFlowDialogEngine/messageStressTest');
/**
* Description of the action goes here
* #param {String} params.name=value Description of the parameter goes here
* #param {Number} [params.age] Optional parameter
*/
/**
* Demo call to MySQL DB
*/
async function dbMysqlConnect(state, event, params) {
var con = mysql.createConnection({
host: configMY.host,
user: configMY.user,
password: configMY.password,
database: configMY.database
})
con.connect(function (err) {
if (err) {
throw err;
}
con.query('select * from users', function (err, result, fields) {
if (err) {
throw err;
}
//console.log(result[0]);
event.reply('#builtin_text', {
text: `User name is : ${result[0].First_name}`,
typing: true
})
})
})
}
Since you're using rewire, you should be able to replace mysql with a mock implementation. I'd recommend sinon as a helpful tool for authoring that mock, though you don't have to do so.
const { stub } = require('sinon');
describe('testing actions.js file', () => {
it('testing dbMysqlConnect function', async () => {
updatedState = _.cloneDeep(initialState);
const router = rewire('../src/actions');
const mockUsers = [];
const mockConnection = {
connect: stub().yields(),
query: stub().yields(null, mockUsers)
};
const mockMySql = {
createConnection: stub().returns(mockConnection);
};
router.__set__('mysql', mockMySql);
const dbMysqlConnect = router.__get__('dbMysqlConnect');
let memoObject = await dbMysqlConnect(updatedState, event);
});
});

NodeJS - 'database.getOneWhere' is not a function

I'm trying to make global database functions, but everytime I try to access them it always says that the object is undefined, and I can't figure out why.
controllers/api/v1/users/index.js:
'use strict';
var path = require('path');
var database = require(path.resolve('database'));
module.exports = function (router) {
router.put('/', function (req, res) {
database.getOneWhere('table', 'row', 'data').then(result => {
//
});
});
}
database/index.js:
'use strict';
const r = require('rethinkdb');
module.exports = async function() {
getOneWhere = async function(table, key, value, callback) {
let conn = await r.connect({host: '127.0.0.1', port: 28015});
let cursor = await r.db('table').table(table).filter(r.row(key).eq(value)).run(conn);
try {
let arr = await cursor.toArray();
callback(arr);
} catch(e) {
callback(e);
}
}
}
It always says that database.getOneWhere is not a function. Any idea how to fix this?
getOneWhere should be a property of module.exports. You defined module.exports as a function and put getOneWhere within that though. It should be:
'use strict';
const r = require('rethinkdb');
module.exports = {
getOneWhere: async function(table, key, value, callback) {
let conn = await r.connect({host: '127.0.0.1', port: 28015});
let cursor = await r.db('table').table(table).filter(r.row(key).eq(value)).run(conn);
try {
let arr = await cursor.toArray();
callback(arr);
} catch(e) {
callback(e);
}
}
};
Or alternatively:
'use strict';
const r = require('rethinkdb');
module.exports.getOneWhere = async function(table, key, value, callback) {
let conn = await r.connect({host: '127.0.0.1', port: 28015});
let cursor = await r.db('table').table(table).filter(r.row(key).eq(value)).run(conn);
try {
let arr = await cursor.toArray();
callback(arr);
} catch(e) {
callback(e);
}
};

Categories

Resources