Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unit test case for basicget.js #234

Merged
merged 7 commits into from
May 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions Node.js/basicget.js
Original file line number Diff line number Diff line change
Expand Up @@ -330,3 +330,5 @@ debug_info('Awaiting for endpoint processing to complete');
Promise.all(promises).then(() => {
debug_info("Sample MQ GET application ending");
});

module.exports = { buildMQDetails, ccdtCheck, initialise, connx, open, close, disconnect, getMessage };
8 changes: 8 additions & 0 deletions Node.js/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,13 @@
},
"engines": {
"node": ">16.0.0"
},
"scripts": {
"test": "mocha"
},
"devDependencies": {
"chai": "^4.4.1",
"mocha": "^10.4.0",
"chai-as-promised": "^7.1.1"
}
}
40 changes: 40 additions & 0 deletions Node.js/test/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# IBM MQ Node.js Samples Unit Tests

The Unit test cases for the Node.js samples have been written in the Mocha JavaScript test framework, along with the Chai Assertion Library. All the dependenices for testing are present in the `devDependencies` section of the `package.json` file. To fetch them, simply run the following command :

`npm i`

## Mocha

Mocha is a feature-rich JavaScript test framework running on Node.js and in the browser. It allows for flexible and accurate reporting, while mapping uncaught exceptions to the correct test cases.

### Installation
Mocha tries to find all the test files under the `test` directory by default. Thus, to leverage the full capabilities of Mocha, it is recommended to install Mocha globally via npm : <br>

`npm install --global mocha`

(Note : This is needed so that you can see the running of the test cases in the terminal)

After installing Mocha globally, simply run the `mocha` command in the terminal, navigating to the Node.js directory of your `mq-dev-patterns` clone :

On Windows:

`<Path to mq-dev-patterns Clone>\mq-dev-patterns\Node.js> mocha`

On Linux/Mac:

`<Path to mq-dev-patterns Clone>/mq-dev-patterns/Node.js$ mocha`

This will lead to mocha searching for all the files ending in `test.js` in the `test` directory, and running them.

## Chai

Chai is a BDD/TDD assertion library for node and the browser that can be delightfully paired with any JavaScript testing framework like Mocha.

( Note : In the `package.json`, the version of Chai is `4.4.1`, since starting from `v5`, Chai is ESM only, and would require to instead use the `import` statement, that throws an error, since the samples in the repository all use the `require` statement to load in libraries. To learn more about this refer to the following link : [ERR_REQUIRE_ESM in v5](https://github.com/chaijs/chai/issues/1561) )

## Good to Know Points

- When testing these samples using IBM MQ on Cloud, it's been observed that due to some network latencies, certain functions like `connx`, `open`, `close` or `disc` could potentially timeout with the default time period of `2000 ms` defined by Chai while testing functions returning Promises. To tackle this, the test cases have been modified with a higher value of `timeout` being assigned to `5000 ms`. In a scenario where this is also not sufficient, you can modify it to a higher value like `10000 ms` to ensure that each of these Promises can be resolved for testing.

- The samples having common functions, for e.g. the `ccdtCheck` function present in the `basicget` as well as the `basicput` files have been tested only once, to avoid leading to duplicate testing, since Mocha will execute all the test files present in the `test` directory by default, unless mentioned explicitly, to test a particular test file.
212 changes: 212 additions & 0 deletions Node.js/test/basicget.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
const { buildMQDetails, ccdtCheck, initialise, connx, open, close, disconnect, getMessage } = require('../basicget');
chughts marked this conversation as resolved.
Show resolved Hide resolved
const mq = require('ibmmq');
const exec = require('child_process').exec;
const envConfig = require('../../env.json');
const chai = require('chai');
const chaiAsPromised = require('chai-as-promised'); // Assertion library of Chai which handles testing of Promise related functions
const { assert, expect } = require('chai');

chai.use(chaiAsPromised);
const envConfigLength = envConfig['MQ_ENDPOINTS'].length;
const MQC = mq.MQC;

describe('buildMQDetails function', () => {
let MQDetails;
let credentials;

beforeEach(() => {
MQDetails = {};
credentials = {};
});

it('Should populate MQDetails and credentials correctly', async () => {
for (let i = 0; i < envConfigLength; i++) {
await buildMQDetails(MQDetails, credentials, i);
expect(MQDetails).to.deep.equal({
QMGR: envConfig.MQ_ENDPOINTS[i].QMGR,
QUEUE_NAME: envConfig.MQ_ENDPOINTS[i].QUEUE_NAME,
HOST: envConfig.MQ_ENDPOINTS[i].HOST,
PORT: envConfig.MQ_ENDPOINTS[i].PORT,
CHANNEL: envConfig.MQ_ENDPOINTS[i].CHANNEL,
KEY_REPOSITORY: envConfig.MQ_ENDPOINTS[i].KEY_REPOSITORY,
CIPHER: envConfig.MQ_ENDPOINTS[i].CIPHER
});

expect(credentials).to.deep.equal({
USER: envConfig.MQ_ENDPOINTS[i].APP_USER,
PASSWORD: envConfig.MQ_ENDPOINTS[i].APP_PASSWORD
})
}
});
});

describe('ccdtCheck function', () => {
let flag;
let CCDT;

it('Should return true if CCDT found in env, else false', () => {
flag = ccdtCheck();
CCDT = "MQCCDTURL";
if (CCDT in process.env) {
expect(flag).to.equal(true);
} else {
expect(flag).to.equal(false);
}
});
});

describe('initialise function', () => {
let cno;
let MQDetails;
let credentials;

beforeEach(() => {
cno = {};
MQDetails = {};
credentials = {};
});

it('Should set SecurityParms in CNO when credentials are provided', async () => {
for (let i = 0; i < envConfigLength; i++) {
await buildMQDetails(MQDetails, credentials, i);
await initialise(cno, MQDetails, credentials);
expect(cno.SecurityParms.UserId).to.equal(envConfig.MQ_ENDPOINTS[i].APP_USER);
expect(cno.SecurityParms.Password).to.equal(envConfig.MQ_ENDPOINTS[i].APP_PASSWORD);
expect(cno.ClientConn).to.exist;
expect(cno.ClientConn.ChannelName).to.equal(envConfig.MQ_ENDPOINTS[i].CHANNEL);
expect(cno.ClientConn.ConnectionName).to.equal(`${envConfig.MQ_ENDPOINTS[i].HOST}(${envConfig.MQ_ENDPOINTS[i].PORT})`);
expect(cno.ClientConn.SSLCipherSpec).to.equal(envConfig.MQ_ENDPOINTS[i].CIPHER_SUITE);
expect(cno.SSLConfig).to.exist;
expect(cno.SSLConfig.KeyRepository).to.equal(envConfig.MQ_ENDPOINTS[i].KEY_REPOSITORY);
}
});
});

describe('connx function', () => {
let cno;
let MQDetails;
let credentials;

beforeEach(() => {
MQDetails = {};
credentials = {};
cno = new mq.MQCNO();
});

it('Should perform MQCONN', async () => {
for (let i = 0; i < envConfigLength; i++) {
await buildMQDetails(MQDetails, credentials, i);
await initialise(cno, MQDetails, credentials);
try {
return assert.isFulfilled(connx(cno, MQDetails));
} catch (err) {
return assert.isRejected(connx(cno, MQDetails));
}
}
}).timeout(5000);
});

describe('open function', () => {
let cno;
let MQDetails;
let credentials;
let od;
let hConn;

beforeEach(() => {
MQDetails = {};
credentials = {};
cno = new mq.MQCNO();
});

it('Should perform MQOPEN', async () => {
for (let i = 0; i < envConfigLength; i++) {
await buildMQDetails(MQDetails, credentials, i);
await initialise(cno, MQDetails, credentials);
hConn = await connx(cno, MQDetails);
od = await open(hConn, MQDetails);
expect(od._name).to.equal(envConfig.MQ_ENDPOINTS[i].QUEUE_NAME);
expect(od._mqQueueManager._name).to.equal(envConfig.MQ_ENDPOINTS[i].QMGR);
expect(od._hObj).to.equal(101);
}
}).timeout(5000);
});

describe('close function', () => {
let cno;
let MQDetails;
let credentials;
let hConn;
let od;
let returnedPromiseVal;

beforeEach(() => {
MQDetails = {};
credentials = {};
cno = new mq.MQCNO();
});

it('Should perform MQCLOSE', async () => {
for (let i = 0; i < envConfigLength; i++) {
await buildMQDetails(MQDetails, credentials, i);
await initialise(cno, MQDetails, credentials);
hConn = await connx(cno, MQDetails);
od = await open(hConn, MQDetails);
return assert.isFulfilled(close(od, i));
}
}).timeout(5000);
});

describe('disc function', () => {
let cno;
let MQDetails;
let credentials;
let hConn;

beforeEach(() => {
MQDetails = {};
credentials = {};
cno = new mq.MQCNO();
});

it('Should perform MQDISC', async () => {
for (let i = 0; i < envConfigLength; i++) {
await buildMQDetails(MQDetails, credentials, i);
await initialise(cno, MQDetails, credentials);
hConn = await connx(cno, MQDetails);
await open(hConn, MQDetails);
return assert.isFulfilled(disconnect(hConn, i));
}
}).timeout(5000);
});

describe('getMessage function', async () => {
let cno;
let MQDetails;
let credentials;
let hConn;
let hObj;
let rcvMsg;

beforeEach(() => {
MQDetails = {};
credentials = {};
cno = new mq.MQCNO();
});

it('Should perform MQGET', async () => {
for (let i = 0; i < envConfigLength; i++) {
await buildMQDetails(MQDetails, credentials, i);
chughts marked this conversation as resolved.
Show resolved Hide resolved
await initialise(cno, MQDetails, credentials);
hConn = await connx(cno, MQDetails);
hObj = await open(hConn, MQDetails);

// We run the basicput sample to put a message into the queue, following which we run the getMessage
// function to retrieve the message we just put.
exec('node basicput.js',async function(err, stdout, stderr){
rcvMsg = await getMessage(hObj);
expect(rcvMsg).to.eventually.equal(true); // This is the method to test a function that returns a promise.
})
}
}).timeout(5000);
});