Sample unit test cases for APIGEE using Jasmine , sample code coverage
One of the important consideration in APIGEE , if Java script is being used extensively is to unit test them using different any of the JS test frameworks. There are quite a few good articles on Mocha , Chai , sinon and few other JS frameworks for this.
I would recommend using Jasmine , which is very easy to pick up and quite robust.
we started with one or two JS files initially but as complexity increased , we did end up writing quite a few. One of the best ways to write JS in apigee is using ES6 standards. we ended up writing /refactoring all our JS using those standards and corresponding unit test cases (specs) and Istanbul for code coverage. You can incorporate this in your CI/CD pipeline along with JSLint , they really help you figure out any JS issues and their behaviour for any changed code as we progress on.
Also refer to the following links to bet a brief understanding of Jasmine
https://daveceddia.com/jasmine-2-spy-cheat-sheet/
https://jasmine.github.io/index.html
Sample JS file - JSAppendIDType
================
/* globals context, module */
var exports = (function () {
'use strict';
return {
run: function (env) {
var context = env.context,
Response = JSON.parse(context.getVariable('response.content')),
resourceType =context.getVariable('resourceType');
if (sageResponse.id) {
Response.id = resourceType + '-' + Response.id;
context.setVariable('response.content', JSON.stringify(Response));
}
}
};
})();
/* jshint expr: true */
typeof context !== 'undefined' && exports.run({context: context});
typeof module !== 'undefined' && (module.exports = exports);
Sample Test script for the above file
=====================================
/* globals jasmine, describe, beforeEach, afterEach, it, expect, spyOn */
/* jshint node: true, esversion: 6 */
var module = require('../apiproxy/resources/jsc/JSAppendIDType');
describe('JSAppendIDType', () => {
it('sets the correct ID prefix when the response.content JSON id field is set', () => {
const mockContext = {
setVariable: () => {},
getVariable: (varName) => {
switch (varName) {
case 'response.content': return JSON.stringify(MOCK_RESPONSE_CONTENT);
case 'resourceType': return 'PUR';
default: throw new Error('Unsupported variable name: ' + varName);
}
}
};
spyOn(mockContext, 'setVariable');
spyOn(mockContext, 'getVariable').and.callThrough();
module.run({context: mockContext});
var setVariableSpyArgs = mockContext.setVariable.calls.mostRecent().args;
expect(setVariableSpyArgs[0]).toEqual('response.content');
expect(JSON.parse(setVariableSpyArgs[1]).id).toEqual('PUR-e247e1');
expect(JSON.parse(setVariableSpyArgs[1]).displayed_as).toEqual('xcnvcxvn');
});
it('does not modify the context when the response.content JSON id field does not exist', () => {
const mockContext = {
setVariable: () => {},
getVariable: (varName) => {
switch (varName) {
case 'response.content':
const mockResponse = Object.assign({}, MOCK_RESPONSE_CONTENT);
delete mockResponse.id;
return JSON.stringify(mockResponse);
case 'resourceType': return 'PUR';
default: throw new Error('Unsupported variable name: ' + varName);
}
}
};
spyOn(mockContext, 'setVariable');
spyOn(mockContext, 'getVariable').and.callThrough();
module.run({context: mockContext});
expect(mockContext.setVariable).not.toHaveBeenCalled();
});
const MOCK_RESPONSE_CONTENT = {
'id': 'e247e1',
'displayed_as': 'xcnvcxvn',
'$path': '/purchase_invoices/e247e1',
'transaction': {
'id': 'e2a7b',
'displayed_as': 'xcnvcxvn',
'$path': '/transactions/e2a7b8d9dbc611'
}
};
});
you need to install few dependencies for running these , create a package.json and install the dependencies
{
"name": "apigee-",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "./node_modules/.bin/istanbul cover ./node_modules/jasmine/bin/jasmine.js -x **/spec/**"
},
"repository": {
"type": "git",
"url": "git"
},
"keywords": [],
"author": "",
"license": "ISC",
"bugs": {
"url": "https://github.com/"
},
"homepage": "https://github.com/,
"dependencies": {},
"devDependencies": {
"istanbul": "^0.4.5",
"jasmine": "^2.8.0",
"jasmine-spec-reporter": "^4.2.1"
}
}
and just execute npm run test