Behavior-Driven JavaScript in APIGEE and their unit testing using Jasmine and Instanbul for code coverage

Not applicable

Sample unit test cases for APIGEE using Jasmine , sample code coverage

0 1 543
1 REPLY 1

Not applicable

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